1006 最长公共子序列Lcs
1 秒 / 131,072 KB / 基础题
问题
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
比如两个串为:
abcicba
abdkscab
ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。输入
第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)输出
输出最长的子序列,如果有多个,随意输出1个。
输入样例
abcicba
abdkscab输出样例
abca
解题时卡在没有想到好的方法输出路径(我用DFS一直错)。办法:记录路径。
如何记录路径:记录此状态的上一步,或者说记录当前是如何由上一步得出的。即:方向。
#include<cstdio> #include<string> #include<iostream> using namespace std; string a,b,ans; const int Max_num=1e3+17; int dp[Max_num][Max_num],book[Max_num][Max_num]; //book[][]记录方向 int main(){ cin>>a>>b; int la=a.length(),lb=b.length(),tail=0; for(int i=0;i<=la;++i) for(int j=0;j<lb;++j) dp[i][j]=0; for(int i=1;i<=la;++i){ for(int j=1;j<=lb;++j){ if(a[i-1]==b[j-1]){ //分三个方向 dp[i][j]=dp[i-1][j-1]+1; book[i][j]=0; } else if(dp[i-1][j]>dp[i][j-1]){ dp[i][j]=dp[i-1][j]; book[i][j]=1; } else{ dp[i][j]=dp[i][j-1]; book[i][j]=2; } } } bool flag=false; for(int i=la;i>0;){ for(int j=lb;j>0;){ if(book[i][j]==0){ ans=a[i-1]+ans; if(j-1>0&&i-1>0) j-=1,i-=1; else{ flag=true;break;} } else if(book[i][j]==1){ if(i-1>0) --i; else{ flag=true;break;} } else{ if(j-1>0)--j; else{ flag=true;break;} } } if(flag)break; } /*for(int i=0;i<=la;++i){ for(int j=0;j<=lb;++j) printf("%d ",dp[i][j]); printf("\n"); } printf("\n"); for(int i=0;i<=la;++i){ for(int j=0;j<=lb;++j) printf("%d ",book[i][j]); printf("\n"); }*/ cout<<ans<<endl; return 0; }
文章来源: https://blog.csdn.net/qq_43482299/article/details/90047125