第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)
输出最长的子序列,如果有多个,随意输出1个。
abcicba abdkscab
abca
思路:通过LCS算出最长公共子序列(自己去找了很多关于这个算法的博客才会的)
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=1100;
int dp[maxn][maxn],num1[maxn],num2[maxn];
int ans[maxn];
char name1[maxn],name2[maxn];
int main()
{
char t;
int i,j,len1,len2,sum;
cin>>name1>>name2;
len1=strlen(name1);
len2=strlen(name2);
for (i=0;i<len1;i++) //这里我把字符改成了数字,方便我后面调试
num1[i+1]=name1[i]-'a'+1;
for (i=0;i<len2;i++)
num2[i+1]=name2[i]-'a'+1;
for (i=1;i<=len1;i++)
for (j=1;j<=len2;j++) //dp[i][j]表示name1到i字符和name2到j字符最大的公共子序列长度是多少
if (num1[i]==num2[j])
dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
sum=0;
memset(ans,0,sizeof(ans));
i=len1;j=len2;
while (i>=1&&j>=1) //查找子序列
{
if ((dp[i][j]==dp[i-1][j]+1)&&(dp[i][j]==dp[i][j-1]+1))
{
ans[sum++]=num1[i];
i--;j--;
}
else if (dp[i-1][j]>dp[i][j-1])
i--;
else j--;
}
for (i=sum-1;i>=0;i--)
printf("%c",ans[i]-1+'a');
printf("\n");
return 0;
}