Codeforces Round #358 (Div. 2) Alyona and Strings

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:

分析:
f[k][i][j]表示s[1].....s[i] 与t[1].....t[j] 中选出k个子串,并且s[i]与t[j]一定是第k个子串的结尾的长度和最大值。
方程:
f[i][j]= -inf (s[i]!=t[j])
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]与前面的一起
}
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]);
}  (二维前缀和思想)
时间复杂度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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值