String
来源:互联网 发布:公寓租房软件 编辑:程序博客网 时间:2024/04/30 22:09
Description
有两种字符串S,T。长度分别为n,m。现在需要在S里面有序地选出k个子串,且在T中出现的顺序与这k个子串的顺序相同。问这k个子串最大的长度和
Input
第一行三个数n,m,k
第二行长度为n的S串
第三行长度为m的T串
Output
一个数表示答案
Sample Input
9 12 4
bbaaababb
abbbabbaaaba
Sample Output
7
Data Constraint
30% n<=10,m<=20
100% n,m<=1000 k<=10
分析
一个显然的思路:设f[i][j][k]表示S串匹配到了第i位,j串匹配到了第j位,取了k个子串的最大值。转移:
f[i][j][k]=max{f[i’][j’][k-1]+len}
其中len是要枚举的,i’≤i-len,j’≤j-len。还要判断S[i-len+1,i]与T[j-len+1,j]是否匹配。
这个转移显然是
优化
对于一个len,枚举的i’和j’可以看成一个矩形,然后可以设
然后上面的方程就变成f[i][j][k]=max{s[i-len][j-len][k-1]+len}
进一步优化
我们发现转移的i-len与j-len的差等于i-j,所以对于相同的i-j和k,把所有s[i][j][k]放在一个单调队列里。时间复杂度降至
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn=1005;int n,m,k,s[maxn][maxn][11],data[maxn*2][maxn][10],h[maxn*2][10],t[maxn*2][10],p[maxn][maxn];char S[maxn],T[maxn];int main(){ freopen("string.in","r",stdin); freopen("string.out","w",stdout); scanf("%d%d%d%s%s",&n,&m,&k,S+1,T+1); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (S[i]==T[j]) p[i][j]=p[i-1][j-1]+1; memset(t,255,sizeof(t)); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { int x=i-j+m,f; for (int T=k-1;T;T--) { for (;h[x][T-1]<=t[x][T-1] && i-data[x][h[x][T-1]][T-1]>p[i][j];h[x][T-1]++); f=(h[x][T-1]<=t[x][T-1])?s[data[x][h[x][T-1]][T-1]][data[x][h[x][T-1]][T-1]-i+j][T-1]+i-data[x][h[x][T-1]][T-1]:0; s[i][j][T]=max(max(s[i-1][j][T],s[i][j-1][T]),f); for (;h[x][T]<=t[x][T] && s[data[x][h[x][T]][T]][data[x][h[x][T]][T]-i+j][T]+i-data[x][h[x][T]][T]<=s[i][j][T];h[x][T]++); data[x][++t[x][T]][T]=i; } f=p[i][j]; s[i][j][0]=max(max(s[i-1][j][0],s[i][j-1][0]),p[i][j]); for (;h[x][0]<=t[x][0] && s[data[x][h[x][0]][0]][data[x][h[x][0]][0]-i+j][0]+i-data[x][h[x][0]][0]<=s[i][j][0];h[x][0]++); data[x][++t[x][0]][0]=i; } int ans=0; for (int i=0;i<k;i++) ans=max(ans,s[n][m][i]); printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0;}
0 0
- string
- String
- String
- string
- string
- String
- string
- String
- string
- string
- string
- string
- String
- String
- string
- string +
- String
- String
- jQuery 之 函数回调与连接方法(五)
- android打包
- keepalived配置tomcat主备
- Intel Media SDK 介绍
- JSP中脚本、声明和表达式的本质区别
- String
- spring学习
- ProtocolBuffers-3.0.0 For Objective C 的快速集成指南
- Log4j的学习--什么是Log4j
- android常见笔试题
- struts2请求过程源码分析
- AnyConnect删除不干净,造成无法重新安装的解决办法
- Android在Fragment中嵌套(添加)Fragment
- oracle利用包向JDBC返回结果集