链接:戳这里
17: LCS
Time Limit: 1 Sec Memory Limit: 128 MB
[Submit][Status][Web Board]
Description
Giving two strings consists of only lowercase letters, find the LCS(Longest Common Subsequence) whose all partition are not less than k in length.
Input
There are multiple test cases. In each test case, each of the first two lines is a string(length is less than 2100). The third line is a positive integer k. The input will end by EOF.
Output
For each test case, output the length of the two strings’ LCS.
Sample Input
abxccdef
abcxcdef
3
abccdef
abcdef
3
Sample Output
4
6
HINT
In the first test case, the answer is:
abxccdef
abcxcdef
The length is 4.
In the second test case, the answer is:
abccdef
abc def
The length is 6
题意:
给出两个串s,p和正整数k
求最长公共子序列的长度 要求每次公共的子序列都必须>=k
思路:
O(n*n)求出长度为1的最长公共子序列
然后在长度>=k且连续的串上取贡献
在用一个二维数组dp[i][j]存下当前i行j列的anw
其实也就是简单的模拟最长公共子序列的过程,只是把一个元素换成了k个元素
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
char s[2200],p[2200];
int k;
int dp[2200][2200],g[2200][2200];
int main(){
while(scanf("%s%s",s,p)!=EOF){
scanf("%d",&k);
mst(dp,0);
mst(g,0);
int n=strlen(s);
int m=strlen(p);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(s[i-1]==p[j-1]) dp[i][j]=dp[i-1][j-1]+1;
}
}
/*for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;*/
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(dp[i][j]>=k && dp[i-k][j-k]>=dp[i][j]-k){
g[i][j]=g[i-k][j-k]+k;
if(dp[i][j]>k) g[i][j]=max(g[i][j],g[i-1][j-1]+1);
}
else g[i][j]=max(g[i-1][j],g[i][j-1]);
/// cout<<g[i][j]<<" ";
}
/// cout<<endl;
}
cout<<g[n][m]<<endl;
}
return 0;
}