最长公共子序列Lcs (51Nod - 1006)
Posted chuixulvcao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子序列Lcs (51Nod - 1006)相关的知识,希望对你有一定的参考价值。
20180604 11:28
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。
Input第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)Output输出最长的子序列,如果有多个,随意输出1个。Sample Input
abcicba abdkscab
Sample Output
abca
思路:
⒈模板题,不过输出的不是最长序列有多长而是最长序列是什么。
⒉详解见代码。
j-1 j
i-1 (i-1,j-1) (i-1,j)
i (i,j-1) (i,j)
求最长公共子序列的思路:
?判断末尾是否相等[if(a[i-1]==b[j-1])]=>c[i][j]=c[i-1][j-1]+1;
?不相等=>c[i][j]=max(c[i][j-1],c[i-1][j]);(及选取最大的);
1 #include<cstdio> 2 #include<cstdlib> 3 #include<iostream> 4 #include<cstring> 5 #include<string> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 int len1,len2; 10 char a[1001],b[1001]; 11 int c[1001][1001]; 12 int main() 13 { 14 cin>>a>>b; 15 len1=strlen(a); 16 len2=strlen(b); 17 memset(c,0,sizeof(c)); 18 int i,j; 19 for(i=1;i<=len1;i++) 20 for(j=1;j<=len2;j++) 21 { 22 if(a[i-1]==b[j-1]) c[i][j]=c[i-1][j-1]+1; 23 else c[i][j]=max(c[i-1][j],c[i][j-1]); 24 } 25 int x=len1; 26 int y=len2; 27 int k=c[x][y];//最长序列出现在右下角.(如果把算出来的c[i][j]画成表格的话) 28 char lcs[1001] = {‘\0‘}; 29 while(i&&j) 30 { 31 if(a[i-1]==b[j-1]&&c[i][j]==c[i-1][j-1]+1)//此时i,j已经到了len1和len2。所以这里是倒着回去看的。 32 {//c[i][j]==c[i-1][j-1]+1证明是从左上角下来的也就是说,左上角位置的a[i-1]和b[j-1]末尾相同。 33 lcs[--k] = a[i-1];//先将k--再用是因为存数据的时候从0开始. 34 i--; 35 j--; 36 } 37 else if(a[i-1]!=b[j-1]&&c[i-1][j]>c[i][j-1]) i--;//看上方图就能明白。 38 else j--; 39 } 40 printf("%s\n",lcs); 41 return 0; 42 }
以上是关于最长公共子序列Lcs (51Nod - 1006)的主要内容,如果未能解决你的问题,请参考以下文章