大概写一下 有时间再完善
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("");
}
}