记录路径的最长公共子序列。。
简单dp,开一个pre数组记录路径,由于 dp[i][j]只能有三种状态推过来,即dp[i-1][j-1],dp[i][j-1],dp[i-1][j],那么我们可以将pre[i][j]分别设为 0 1 2 ,最后只要递归扫一遍就可以了。。
#include<iostream>
#include<sstream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=105;
string s[2][maxn];
int dp[maxn][maxn];
int pre[maxn][maxn];
int len[2];
void getlcs(){
for(int i=0;i<len[0];i++){
dp[i][0]=0;
for(int j=0;j<len[1];j++){
dp[0][j]=0;
if(s[0][i]==s[1][j]){
dp[i+1][j+1]=dp[i][j]+1;
pre[i+1][j+1]=0;
}
else {
if(dp[i+1][j]>dp[i][j+1])dp[i+1][j+1]=dp[i+1][j],pre[i+1][j+1]=1;
else dp[i+1][j+1]=dp[i][j+1],pre[i+1][j+1]=2;
}
}
}
}
void printpre(int len0,int len1){
if(len0==0||len1==0)return;
if(pre[len0][len1]==0){
printpre(len0-1,len1-1);
if(len0==1)cout<<s[0][len0-1];
else cout<<" "<<s[0][len0-1];
}
else if(pre[len0][len1]==1)printpre(len0,len1-1);
else printpre(len0-1,len1);
}
int main(){
string input;
while(cin>>s[0][0]){
for(int i=0;i<2;i++){
int cnt=(i==0?1:0);
while(1){
getline(cin,input);
stringstream sin(input);
while(sin>>input){
if(input=="#")goto endinput;
else s[i][cnt++]=input;
}
}
endinput:;
len[i]=cnt;
}
getlcs();
//cout<<dp[len[0]][len[1]]<<endl;
printpre(len[0],len[1]);
cout<<endl;
}
}