51Nod1006:最長公共子序列Lcs
阿新 • • 發佈:2018-12-06
https://www.51nod.com/Challenge/Problem.html#!#problemId=1006
給出兩個字串A B,求A與B的最長公共子序列(子序列不要求是連續的)。
比如兩個串為:
abcicba
abdkscab
ab是兩個串的子序列,abc也是,abca也是,其中abca是這兩個字串最長的子序列。
輸入
第1行:字串A
第2行:字串B
(A,B的長度 <= 1000)
輸出
輸出最長的子序列,如果有多個,隨意輸出1個。
輸入樣例
abcicba
abdkscab
輸出樣例
abca
#include<stdio.h> #include<string.h> #define N 1020 char str1[N],str2[N],ans[N]; int dp[N][N]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,len1,len2,len; while(scanf("%s %s",str1+1,str2+1)!=EOF) { memset(dp,0,sizeof(dp)); len1=strlen(str1+1); len2=strlen(str2+1); for(i=1;i<=len1;i++) for(j=1;j<=len2;j++) { if(str1[i]==str2[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } i=len1;j=len2; len=0; while(i&&j) { if(str1[i]==str2[j]) { ans[len]=str1[i]; len++; i--; j--; } else if(dp[i][j]==dp[i-1][j]) i--; else if(dp[i][j]==dp[i][j-1]) j--; } len--; for(i=len;i>=0;i--) printf("%c",ans[i]); printf("\n"); } return 0; }
如果想讓輸出不同的答案,只需要做一點點改動,兩種答案都對。
#include<stdio.h> #include<string.h> #define N 1020 char str1[N],str2[N],ans[N]; int dp[N][N]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,len1,len2,len; while(scanf("%s %s",str2+1,str1+1)!=EOF) //改動 { memset(dp,0,sizeof(dp)); len1=strlen(str1+1); len2=strlen(str2+1); for(i=1;i<=len1;i++) for(j=1;j<=len2;j++) { if(str1[i]==str2[j]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } i=len1;j=len2; len=0; while(i&&j) { if(str1[i]==str2[j]&&dp[i-1][j-1]!=dp[i][j]) { ans[len]=str1[i]; len++; i--; j--; } else if(dp[i][j]==dp[i-1][j]) i--; else if(dp[i][j]==dp[i][j-1]) j--; } len--; for(i=len;i>=0;i--) printf("%c",ans[i]); printf("\n"); } return 0; }