D. Alyona and Strings
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
题意:
给出两个字符串 s[1]s[2].......s[n], t[1]t[2]........t[n]
找出k个s的不相交子串,他们同时也依次是t的不相交子串 ,求这些字串长度之和最大值.
Output
In the only line print the only non-negative integer — the sum of the lengths of the strings in a desired sequence.
It is guaranteed, that at least one desired sequence exists.
Examples
input
3 2 2 abc ab
output
2
input
9 12 4 bbaaababb abbbabbaaaba
output
7
Note
The following image describes the answer for the second sample case:
![](https://i-blog.csdnimg.cn/blog_migrate/a686b2359407a39e571b96bc76d0d0eb.png)
f[i][j] =max{
f[k][i][j]= max{f[k-1][p][q]}+1 k-1<=p<=i ,k-1<=q<=j, s[i]==t[j] //s[i]单独一段
f[k][i][j]=f[k][i-1][j-1]+1 s[i]==t[j]&&s[i-1]==t[j-1]; //s[i]与前面的一起
f[k][i][j]=f[k][i-1][j-1]+1 s[i]==t[j]&&s[i-1]==t[j-1]; //s[i]与前面的一起
}
k一定的情况下,max{f[k-1][p][q]}其实表示的是f数组中一块矩形中的最大值
记best[i][j]=max{f[k-1][p][q]}
那么best[i-1][j-1]=max{ best[i-1][j-2]);
best[i-2][j-1]);
f[k-1][i-1][j-1]);
best[i-2][j-1]);
f[k-1][i-1][j-1]);
} (二维前缀和思想)
时间复杂度O(n*m*k)
代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1000+5,inf=1e9;
int n,m,K,f[11][maxn][maxn],best[maxn][maxn],ans=0;
char s[maxn],t[maxn];
int main(){
//freopen("data.in","r",stdin);
//freopen("myans.out","w",stdout);
int i,j,k;
scanf("%d%d%d",&n,&m,&K);
scanf("%s%s",s+1,t+1);
for(k=0;k<=K;k++)
for(i=0;i<=n;i++)
for(j=0;j<=m;j++)f[k][i][j]=-inf;
for(k=1;k<=K;k++){
memset(best,0,sizeof(best));
for(i=k;i<=n;i++){
best[k-1][k-1]=max(f[k-1][k-1][k-1],0);
for(j=k;j<=m;j++){
if(j>1)
best[i-1][j-1]=max(best[i-1][j-1],best[i-1][j-2]);
if(i>1)
best[i-1][j-1]=max(best[i-1][j-1],best[i-2][j-1]);
best[i-1][j-1]=max(best[i-1][j-1],f[k-1][i-1][j-1]);
if(s[i]==t[j])
f[k][i][j]=max(f[k][i][j],best[i-1][j-1]+1);
if(s[i]==t[j]&&s[i-1]==t[j-1])
f[k][i][j]=max(f[k][i][j],1+f[k][i-1][j-1]);
}
}
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
ans=max(ans,f[K][i][j]);
printf("%d\n",ans);
return 0;
}