大概写一下 有时间再完善
1.用vir[][][]数组记录此次选择的上一个选择位置
2.数组cc[][]记录此次选择的最长公共子序列的最后一位的在a字符串的下标 cc[i][j]=0表示从上个位置到此次位置没有更新更好的
回溯 数组cc里面存的就是最长公共子序列
/* 最长公共子序列之回溯 */ #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<cstdlib> #define N 1300 #define INF 0x3f3f3f3f using namespace std; int vir[N][N][2],cc[N][N]; int dp[N][N]; int lcs(char* a,char* b,int la,int lb) { memset(dp,0,sizeof(dp)); memset(cc,0,sizeof(cc)); for(int i=1; i<=la; i++) for(int j=1; j<=lb; j++) { if(a[i]==b[j]) { dp[i][j]=dp[i-1][j-1]+1; vir[i][j][0]=i-1; vir[i][j][1]=j-1; cc[i][j]=i; } else { cc[i][j]=0; if(dp[i-1][j]>=dp[i][j-1]) { dp[i][j]=dp[i-1][j]; vir[i][j][0]=i-1; vir[i][j][1]=j; } else { dp[i][j]=dp[i][j-1]; vir[i][j][0]=i; vir[i][j][1]=j-1; } } } return dp[la][lb]; } int main() { char s1[N],s2[N]; int res[N],la,len1,len2,ii,jj; int t=5; while(t--) { scanf("%s %s",s1+1,s2+1); len1=strlen(s1+1); len2=strlen(s2+1); lcs(s1,s2,len1,len2); la=0; ii=len1; jj=len2; int mi,mj; while(ii&&jj) { if(cc[ii][jj]) { res[la++]=cc[ii][jj]; } mi=ii;//回溯 mj=jj; ii=vir[mi][mj][0]; jj=vir[mi][mj][1]; } // for(int i=0;i<la;i++) // printf("%d ",res[i]); puts("--------"); printf("the most len ss:"); for(int i=la-1;i>=0;i--) printf("%c",s1[res[i]]); puts(""); } }