其实就是一个最长公共子序列的问题,不过要打印路径。对于路径打印,可以采取0-1背包问题的方法,第一可以利用一个二维数组记录每个状态的指向最后再由最后一个状态
回推,第二可以直接由最后一个状态结合前面的状态转移进行路径打印;下面的代码采用了第二种方法。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main()
{
char str1[150][33],str2[150][35],temp[50];
int dp[150][150];
while(scanf("%s",temp)!=EOF)
{
int len1=1,len2=1;
while(1)
{
if(temp[0]=='#')
break;
strcpy(str1[len1++],temp);
scanf("%s",temp);
}
scanf("%s",temp);
while(1)
{
if(temp[0]=='#')
break;
strcpy(str2[len2++],temp);
scanf("%s",temp);
}
memset(dp,0,sizeof(dp));
for(int i=1;i<len1;i++)
for(int j=1;j<len2;j++)
{
if(strcmp(str1[i],str2[j])==0)
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
int i=len1-1,j=len2-1,k=0;
char ans[150][34];
while(1)
{
if(strcmp(str1[i],str2[j])==0)
{
strcpy(ans[k++],str1[i]);
i--;j--;
}
else
{
if(dp[i-1][j]>dp[i][j-1])
i=i-1;
else
j=j-1;
}
if(i==0||j==0)
break;
}
for(i=k-1;i>=1;i--)
printf("%s ",ans[i]);
printf("%s\n",ans[0]);
}
return 0;
}