题意:字典里有W个词,输入一个长度为L的字符串,求最少删除几个字母后使得字符串里的所有词都可以在字典里找到。
思路:从字符串的左端开始每移动一位都先默认这些字符都需要删除,因为没有找到匹配的单词即 dp[i]=dp[i-1]+1 直到指针移动的长度在字典里能够找到单词,找到相同长度单词后,从单词末尾和指针之前的字符匹配如果可以完全把字典里的单词匹配完,此时意味着之前删除的部分字符无效,真正需要删除的字符只有(设位置指针为i,查找指针为k,单词长度为len)那么就是i-k-len个字符,此时更新dp数组。得到的状态转移方程为
dp[i]=dp[i-1]+1; //不能匹配到单词
dp[i]=min(dp[i],dp[k]+i-k-len[j]); //匹配到了单词
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[400];
char dic[620][30];
int len[400];
int main()
{
int w,l;
int i,j,k;
char str[400];
scanf("%d%d%*c",&w,&l);
scanf("%s",str);
for(i=0;i<w;i++)
{
scanf("%s",dic[i]);
len[i]=strlen(dic[i]);
}
for(i=0;i<l;i++)
{
dp[i]=dp[i-1]+1;
for(j=0;j<w;j++)
{
int len_d=len[j]-1;
k=i;
if(len_d>k) continue;
while(len_d>=0&&k>=0&&k>=len_d)
{
if(dic[j][len_d]==str[k]) len_d--;
k--;
}
if(len_d<0)
dp[i]=min(dp[i],dp[k]+i-k-len[j]);
}
}
printf("%d\n",dp[l-1]);
return 0;
}