題意:字典裏有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;
}