最长公共子序列的变形 就是要求输出路径 用个vis记录一下 回溯输出就可以了
#include <algorithm> #include <cstring> #include <cstdio> using std::max; int n,m,q; char str[50]; char s[110][35]; char s2[110][35]; int dp[110][110]; char s3[110][35]; struct dat { int a,b; int ok; } vis[110][110]; bool solve(int x,int y) { if(strcmp(s[x],s2[y])) return false; return true; } void dfs(int x, int y) { if(x==-1 || y==-1 ) return ; int aa=vis[x][y].a; int bb=vis[x][y].b; if(vis[x][y].ok) { dfs(aa,bb); strcpy(s3[q++],s[x]); } else if(!vis[x][y].ok) dfs(aa,bb); } int LCS(int x, int y) { if(x==-1 || y==-1) return 0; if(dp[x][y]!=-1) return dp[x][y]; if(solve(x, y)) { vis[x][y].a=x-1; vis[x][y].b=y-1; vis[x][y].ok=1; return dp[x][y]=LCS(x-1, y-1)+1; } else { int nn=LCS(x-1, y); int mm=LCS(x,y-1); if(nn>mm) { vis[x][y].a=x-1; vis[x][y].b=y; vis[x][y].ok=0; return dp[x][y]=nn; } else { vis[x][y].a=x; vis[x][y].b=y-1; vis[x][y].ok=0; return dp[x][y]=mm; } } } int main() { char ch; while(scanf("%s%c",str,&ch)==2) { if(strcmp("#",str)) { strcpy(s[0],str); n=1; while(scanf("%s%c",str,&ch)==2) { if(!strcmp("#",str)) break; strcpy(s[n++],str); } } m=0; while(scanf("%s%c",str,&ch)==2) { if(!strcmp("#",str)) break; strcpy(s2[m++],str); } memset(dp, -1, sizeof(dp)); memset(vis, -1, sizeof(vis)); LCS(n-1,m-1); q=0; dfs(n-1,m-1); for(int i=0; i<q; i++) if(!i) printf("%s",s3[i]); else printf(" %s",s3[i]); puts(""); } return 0; }