【JZOJ 4595】 String

来源:互联网 发布:电视网络机顶盒多少钱 编辑:程序博客网 时间:2024/05/21 19:47

Description

有两种字符串A,B。长度分别为n,m。现在需要在S里面有序地选出k个子串,且在B中出现的顺序与这k个子串的顺序相同。问这k个子串最大的长度和。
吐槽:题意不清。
有序地的意思是子串从左到右选
选的各个子串不能重复、重叠
100% n,m<=1000 k<=10

Analysis

一眼DP
可是DP有技巧
f[i][j][k]表示AiBj,分了k个字串,则f[i][j][k]=max(f[i1][j1][k]+1   ,   i[1,i1],j[1,j1]f[i][j][k1]+1)
枚举i,j其实不需要,再弄一个数组存下来f的前缀最大值即可。
O(nmk)

Code

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)using namespace std;const int N=1010,K=12;int n,m,r,f[N][N][K][2];char a[N],b[N];int main(){    freopen("string.in","r",stdin);    freopen("string.out","w",stdout);    int ans=0;    scanf("%d %d %d\n%s\n%s",&n,&m,&r,a+1,b+1);    fo(k,1,r)    {        fo(i,1,n)        {            fo(j,1,m)            {                f[i][j][k][0]=max(f[i][j-1][k][0],f[i-1][j][k][0]);                f[i][j][k][0]=max(f[i][j][k][0],f[i][j][k][1]);                if(a[i]==b[j])                {                    f[i][j][k][1]=max(f[i][j][k][1],f[i-1][j-1][k-1][0]+1);                    f[i][j][k][1]=max(f[i][j][k][1],f[i-1][j-1][k][1]+1);                    f[i][j][k][0]=max(f[i][j][k][0],f[i][j][k][1]);                }                if(k==r) ans=max(ans,f[i][j][r][1]);            }        }    }    printf("%d",ans);    return 0;}
0 0
原创粉丝点击