Giving two strings consists of only lowercase letters, find the LCS(Longest Common Subsequence) whose all partition are not less than k in length.
Giving two strings consists of only lowercase letters, find the LCS(Longest Common Subsequence) whose all partition are not less than k in length.
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.
For each test case, output the length of the two strings’ LCS.
abxccdef
abcxcdef
3
abccdef
abcdef
3
4
6
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
如样例1:
abxccdef
abcxcdef
最长公共子序列由ab+ccdef abc+cdef(或abx+cdef ab+xcdef)组成,因为子串ab长度小于3,故只取子串cdef,故最长公共子序列(子串长度>=k)长度为4
很明显,此题是最长公共子序列的变形,要解决此题,首先我们要理解简单版的最长公共子序列如何求解
作为变形,当s1[i-1]!=s2[j-1]时,我们不能再继承之前的maxLen值了,因为在这里发生了断裂,即这里开始不连续,故maxLen[i][j]=0;
待我们处理好maxLen[][]数组之后,我们才开始计算最长公共子序列(子串长度>=k)
令dp[i][j]表示s1的左边i个字符形成的子串,与s2左边的j个字符形成的子串的最长公共子序列的长度(i,j从0开始算,子串长度>=k)
我们可以得到转移方程
/*Sherlock and Watson and Adler*/ #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<cmath> #include<complex> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 2105; const int M = 40; const int inf = 100000000; const int mod = 2009; char s1[N],s2[N]; int maxLen[N][N],dp[N][N]; int main() { int k,i,j,l1,l2; while(~scanf("%s",s1)) { scanf("%s",s2); scanf("%d",&k); l1=strlen(s1); l2=strlen(s2); for(i=0;i<=l1;i++) maxLen[i][0]=0; for(i=0;i<=l2;i++) maxLen[0][i]=0; memset(dp,0,sizeof(dp)); for(i=1;i<=l1;i++) for(j=1;j<=l2;j++) if(s1[i-1]==s2[j-1]) maxLen[i][j]=maxLen[i-1][j-1]+1; else maxLen[i][j]=0; /*for(i=1;i<=l1;i++) { for(j=1;j<=l2;j++) printf("%d ",maxLen[i][j]); puts(""); } puts("");*/ for(i=1;i<=l1;i++) for(j=1;j<=l2;j++) if(maxLen[i][j]>=k) dp[i][j]=max(dp[i-1][j-1]+1,dp[i-k][j-k]+k); else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); /*for(i=1;i<=l1;i++) { for(j=1;j<=l2;j++) printf("%d ",dp[i][j]); puts(""); }*/ printf("%d\n",dp[l1][l2]); } return 0; }
菜鸟成长记