POJ 3267 The Cow Lexicon DP

题意:给定一条原始字符序列,以及一些单词,问至少去掉多少个字母才能使原始序列全部由单词组合而成。
题解:
dp [ i ] 表示在第 i 个字母之前最少要删除的字母个数。
枚举原始序列的每一个字母,0,1,2,3····。只有删与不删两种状态。假设删掉第 i 个字母,则 dp [ i ] = dp [ i - 1 ] + 1; 假设不删掉第 i 个字母,那么令 i 是某个单词的最后一个字母,因此我们在原始序列中从 i 开始往前与每个单词进行比较,寻找满足条件的单词。 找到之后, dp [ i ] = dp [ 单词首字母在原始序列中的位置 - 1 ] + ( 单词尾字母位置 - 单词首字母位置 + 1 ) - 单词长度。

#include <iostream>
using namespace std;

int w, l;
int dp[605], len[605];
char words[605][30], str[305];

int min ( int a, int b )
{
	return a < b ? a : b;
}

int main()
{
	int i, j, k, t;

	//freopen("a.txt","r",stdin);
	scanf("%d%d",&w,&l);
	scanf("%s",str);

	for ( i = 0; i < w; i++ )
	{
		scanf("%s",words[i]);
		len[i] = strlen(words[i]);
	}
	
	memset(dp,0,sizeof(dp));

	for ( i = 1; i <= l; i++ )
	{
		dp[i] = dp[i-1] + 1;
		for ( j = 0; j < w; j++ )
		{
			k = len[j] - 1;
			t = i - 1;
			while ( k >= 0  && t >= 0 )
			{
				if ( words[j][k] == str[t] )
					k--;
				t--;
			}
			if ( k < 0 )
				dp[i] = min ( dp[i], dp[t+1] + (i-1) - t - len[j] );
		}
	}

	printf("%d\n",dp[l]);
	return 0;
}


你可能感兴趣的:(POJ 3267 The Cow Lexicon DP)