码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1633 / P2875 [USACO07FEB]牛的词汇The Cow Lexicon

时间:2018-12-04 14:47:45      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:字母   The   cow   icon   技术   span   opened   直接   clu   

P2875 [USACO07FEB]牛的词汇The Cow Lexicon

三维dp

它慢,但它好写。

直接根据题意设三个状态:

$f[i][j][k]$表示主串扫到第$i$个字母,匹配到第$j$个单词的第$k$位可以留下的最多字符数

当该位不选时,就传递上一位的数据$f[i][j][k]=f[i-1][j][k]$

当该位可以匹配时:

$if(a[i]==b[j][k]\&\&f[i-1][j][k-1])$
$f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+1);$

注意不允许有重叠单词所以要判断前一位

当匹配完一个单词时,就要跳到一个新单词的第一位上,那么:

$f[i][j][1]=max(f[i][j][1],f[i-1][u][len[u]]+1)$

最后用主串的长度减去可留下字符数就是答案了。

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int max(int &a,int &b){return a>b?a:b;}
 6 int m,n,f[305][605][30],len[605],ans;
 7 char a[305],b[605][30];
 8 void output(int x){//debug
 9     cout<<"x:"<<x<<endl;
10     for(int i=1;i<=m;++i,cout<<endl)
11         for(int j=1;j<=len[i];++j)
12             cout<<f[x][i][j]<<" ";
13     cout<<endl<<endl;
14 }
15 int main(){
16     scanf("%d%d",&m,&n); scanf("%s",a+1);
17     for(int i=1;i<=m;++i)
18         scanf("%s",b[i]+1),len[i]=strlen(b[i]+1);
19     for(int i=1;i<=n;++i)
20         for(int j=1;j<=m;++j){
21             for(int k=1;k<=len[j];++k){
22                 f[i][j][k]=f[i-1][j][k];
23                 if(a[i]==b[j][k]&&f[i-1][j][k-1])
24                     f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]+1);
25             }
26             if(a[i]==b[j][1])
27                 for(int u=1;u<=m;++u)
28                     f[i][j][1]=max(f[i][j][1],f[i-1][u][len[u]]+1);
29         }
30     for(int i=1;i<=m;++i) ans=max(ans,f[n][i][len[i]]);
31     printf("%d",strlen(a+1)-ans);
32     cout<<endl;
33     return 0;
34 }
View Code

 

bzoj1633 / P2875 [USACO07FEB]牛的词汇The Cow Lexicon

标签:字母   The   cow   icon   技术   span   opened   直接   clu   

原文地址:https://www.cnblogs.com/kafuuchino/p/10063465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!