题意:从给定字符串
browndcodw中删除给定单词,每个单词可删多次,答案为2即browndcodw-cow-brown=2。
分析:动态规划,状态f[i]
定为:从字符串str[i]往后删单词需要删几个,状态转移:若不能删则f[i]=f[i+1]+1;
若以str[i]开头的单词可以被删,则f[i]=MIN(f[i],f[k+1]+k+1-i-cur);即str中匹配长度-单词长度+str剩余部分状态,不好理解,举例:str中codw与cow匹配,f[k+1]+k+1-i-cur为f[w下一个位置的状态]+匹配长度需要删除的(codw-cow)
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=650;
const int MAXM=350;
char da[MAXN][MAXM];
char str[MAXM];
int f[MAXM];
int MIN(const int a,const int b){ return a>b?b:a;}
int main()
{
int n,l,i,j,k;
// freopen("123.txt","r",stdin);
while(~scanf("%d%d",&n,&l))
{
scanf("%s",str);
for(i=0;i<n;i++)
scanf("%s",da[i]);
f[l]=0;
for(i=l-1;i>=0;i--)
{
f[i]=f[i+1]+1;
for(j=0;j<n;j++)
if(da[j][0]==str[i]&&l-i>=strlen(da[j]))
{
int cur=0;
for(k=i;k<l;k++)
if(str[k]==da[j][cur])
{
cur++;
if(cur==strlen(da[j]))
{
f[i]=MIN(f[i],f[k+1]+k+1-i-cur);
break;
}
}
}
}
printf("%d\n",f[0]);
}
return 0;
}