题意:给定一条原始字符序列,以及一些单词,问至少去掉多少个字母才能使原始序列全部由单词组合而成。
题解:
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; }