POJ 3267 The Cow Lexicon DP 字符串匹配问题扩展
<strong><span style="font-size:18px;">/*题意:给一个主串 和n个子串 问最少在主串删除多少字母,可以使其匹配到 n 个单词序列中的一些
思路:dp[i] 表示从主串开头的字母到第 i 个字母最少需要删除字符的个数(即主串长度为i时)
d[i]=min( d[j]+dele //如果S[j+1..i]子串中包含了一个单词,j<=i
d[i-1]+1 ) //如果不存在可包含单词的子串| 最坏情况
dele为要删的字符的个数 dele=匹配位置-终止位置-单词长度
*/</span></strong>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
char s[400];
char ss[650][30];
int len[650];
int dp[400];
int main()
{
int n,L;
while(~scanf("%d%d",&n,&L))
{
scanf("%s",s);
for(int i=1; i<=n; i++)
{
scanf("%s",ss[i]);
len[i]=strlen(ss[i]);
}
for(int i=0; i<L; i++)
{
if(!i)
dp[i]=1;
else
dp[i]=dp[i-1]+1; //最坏的情况
for(int k=1; k<=n; k++)
{ //从i开始查找匹配
int lenth=len[k]-1,j=i,dele=0;
while(lenth>=0&&j>=0&&j-lenth>=0)
{
if(s[j]==ss[k][lenth])
lenth--;
j--;
}
if(lenth<0) //只有整个单词都匹配了 才进行改变
{
dele=i-j-len[k]; //多出来的(需要删除的部分)
dp[i]=min(dp[i],dp[j]+dele); //更新状况<span id="transmark"></span>
}
}
}
printf("%d\n",dp[L-1]);
}
return 0;
}