题目大意:奶牛发送的消息可能有干扰字母,问至少删除几个字母能让它成为有意义的消息(在奶牛字典里存在的)
输入:字典包含词的个数W 消息长度L
发送的消息
字典里面的单词1
字典里面的单词2...
输出:删除字母个数
分析:从前往后动态规划
消息字符串长度m,字典中单词个数n
状态dp[i]:前i个字母中删除的字符个数
结果:dp[m]
初始化:dp[0]=0
状态转移方程:dp[i]=dp[i-1]+1;(最坏情况)
若匹配成功则取最优值dp[i]=min{dp[i],dp[i-x]+x-lb};
匹配过程:当单词长度lb小于当前i且单词尾字母和第i位吻合时,才进行匹配。x为消息字符串指针走过的字符个数,当x大于i时,匹配失败跳出循环,dp[i]不变。逐个字符匹配,吻合时x++,y--(y为单词指针,从词尾开始),否则x++,y不动,当y=0(到达单词开头)时,匹配成功,进行dp[i]优化。
代码:以下参考http://www.bubuko.com/infodetail-253439.html
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int n,m;
int i,j;
char a[610],b[1005][1005];//a为消息字符串,b为字典中的n个单词
int dp[610];
int lb;
int x,y;
while(cin>>n>>m)
{
cin>>a+1;
for(i=0;i<n;i++)
cin>>b[i]+1;
dp[0]=0;
for(i=1;i<=m;i++)
{
dp[i]=dp[i-1]+1;//如果无法匹配
for(j=0;j<n;j++)
{
lb=strlen(b[j]+1);
x=0;y=lb;
if(i>=lb&&a[i]==b[j][lb])
{
while(i-x>0)
{
if(a[i-x]==b[j][y])
{x++;y--;}
else x++;
if(!y)
{
dp[i]=min(dp[i],dp[i-x]+x-lb);
break;
}
}
}
}
}
cout<<dp[m]<<endl;
}
return 0;
}