算法复习之::LCS最长公共子序列
算法思想:dp[i][j]记录到A[i],B[j]的位置是Lcs的最大长度,
转移方程:I:dp[i][j]=max(dp[i-1][j],dp[i][j]) (i>1)
II:dp[i][j]=max(dp[i][j-1],dp[i][j]) (j>1)
III:dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1) (A[i]==A[j],i>1,j>1)
处理完后,再从dp[A.length][B.length]处开始回溯找出最大子序列。
代码:
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; char A[100],B[100]; int dp[110][110],cnt; char ans[110]; void ini() { cnt=0; scanf("%s",A); scanf("%s",B); memset(dp,0,sizeof(dp)); memset(ans,'\0',sizeof(ans)); } void DP() { int a=strlen(A),b=strlen(B); for(int i=0;i<a;i++) for(int j=0;j<b;j++) { if(i>0) dp[i][j]=max(dp[i-1][j],dp[i][j]); if(j>0) dp[i][j]=max(dp[i][j],dp[i][j-1]); if(A[i]==B[j]) { if(i==0 || j==0) dp[i][j]=max(dp[i][j],1); else dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1); } } } void dfs(int i,int j) { if(i==0 || j==0) { if(A[i]==B[j]) ans[cnt++]=A[i]; return; } if(A[i]==B[j] && dp[i][j]>dp[i-1][j-1] && dp[i][j]>dp[i-1][j] && dp[i][j]>dp[i][j-1]) { ans[cnt++]=A[i]; dfs(i-1,j-1); } else { if(dp[i][j]==dp[i-1][j-1]) dfs(i-1,j-1); else if(dp[i][j]==dp[i][j-1]) dfs(i,j-1); else dfs(i-1,j); } } int main() { ini(); DP(); dfs(strlen(A)-1,strlen(B)-1); for(int i=alen-1;i>=0;i--) cout<<ans[i]; return 0; }