给出两个字符串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
求最长公共子序列是dp的思想,先分类:
- 第i-1个和第j-1个字母相同的情况,那么dp[i][j]的长度为dp[i-1][j-1]+1;
- 第i-1个和第j-1个字母不相同的情况,又分为两种情况。
然后通过回溯法输出该字符串。
上一张图,(虽然不太清楚....)以 ABCBDAB BDCABA 为例。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<math.h> 5 #include<algorithm> 6 #include<queue> 7 #include<stack> 8 #include<deque> 9 #include<iostream> 10 using namespace std; 11 typedef long long LL; 12 char str1[1009],str2[1009]; 13 int dp[1009][1009]; 14 void output(int i,int j) 15 { 16 if(i==0||j==0) 17 return ; 18 else 19 { 20 if(str1[i-1]==str2[j-1]) 21 { 22 output(i-1,j-1); 23 printf("%c",str1[i-1]); 24 } 25 else 26 { 27 if(dp[i][j-1]>=dp[i-1][j]) 28 output(i,j-1); 29 else 30 output(i-1,j); 31 32 } 33 } 34 } 35 int main() 36 { 37 int i,p,j; 38 int len1,len2; 39 40 scanf("%s%s",str1,str2); 41 memset(dp,0,sizeof(dp)); 42 len1=strlen(str1); 43 len2=strlen(str2); 44 for(i=1; i<=len1; i++) 45 for(j=1; j<=len2; j++) 46 { 47 if(str1[i-1]==str2[j-1]) 48 dp[i][j]=dp[i-1][j-1]+1; 49 else 50 dp[i][j]=max(dp[i][j-1],dp[i-1][j]); 51 } 52 output(len1,len2); 53 putchar(' '); 54 return 0; 55 }