给定两个字符串s1s2...sn和t1t2...tn。求出这两个字符串最长的公共子序列
输入:
abcicba
abdkscab
输出:
s1…si+1和t1…tj+1对应的公共子列有三种情况:
①当si+1= tj+1时,在s1…si和t1…tj的公共子列末尾追加上si+1
②s1…si和t1…tj+1的公共子列
③s1….si+1和t1…tj的公共子列
所以有
dp[i+1][j+1] = max(dp[i][j]+1,dp[i][j+1], dp[i+1][j]) (si+1=tj+1)
= max(dp[i][j+1], dp[i+1][j])
Dp[n][m]就是LCS的长度
然后从后往前判断LCS中的字符即可
输入:
abcicba
abdkscab
输出:
abca
s1…si+1和t1…tj+1对应的公共子列有三种情况:
①当si+1= tj+1时,在s1…si和t1…tj的公共子列末尾追加上si+1
②s1…si和t1…tj+1的公共子列
③s1….si+1和t1…tj的公共子列
所以有
dp[i+1][j+1] = max(dp[i][j]+1,dp[i][j+1], dp[i+1][j]) (si+1=tj+1)
= max(dp[i][j+1], dp[i+1][j])
Dp[n][m]就是LCS的长度
然后从后往前判断LCS中的字符即可
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
char a[1003], b[1003], c[1003];
int dp[1003][1003];
int main()
{
while (cin > > a > > b)
{
int n = strlen(a);
int m = strlen(b);
memset(dp, 0, sizeof(dp));
for (int i = 1; i < = n; i++)
for (int j = 1; j < = m; j++)
{
if (a[i-1] == b[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
int i = n, j = m, k = dp[n][m];
c[k--] = '\0';
while (i & & j)
{
if (k < 0)
break;
if (a[i-1] == b[j-1])
{
c[k--] = a[i-1];
i--;
j--;
}
else if (dp[i][j-1] > = dp[i-1][j])
j--;
else
i--;
}
cout << c << endl;
}
return 0;
}