问题描述
给出两个字符串,求出这样的一个最长的公共子序列的长度:子序列中的每个字符都能在两个原串中找到,而且每个字符的先后顺序和原串中的先后顺序一致。
例如:abcfbc与abfcab的最长公共子序列是abcb
输入样例
2
asdf
adfsd
123abc
abc123abc
输出样例
3
6
我们要用一个二维数组(dp[MAX_N][MAX_N])来存放每一个状态的值。如图所示,横向代表i、纵向代表j,那么,每一个网格的值是怎么来的呢。在这里我们把每一个状态即dp[i][j] 看做 s1 … si 和 t1 … tj 的LCS的长度。由此我们,s1 … s(i+1) 和 t1 … t(j+1) 对应的公共子列长度可能是:
当s(i+1) == t(j+1),在 s1 … si 和 t1 … tj 的公共子列末尾追加上s(i+1) 。
否则则可能是 s1 … si 和 t1 … t(j+1) 的公共子列或者 s1 … s(i+1) 和 t1 … tj 的公共子列最大值。
#include <iostream>
#include <cstring>
using namespace std;
int f[2010][2010];
char a[2010], b[2010];
int max(int a, int b)
{
if (a >= b)
return a;
return b;
}
int main()
{
int i, j, len1, len2;
cin >> a >> b;
len1 = strlen(a);
len2 = strlen(b);
for (i = 1; i <= len1; i++)
{
for (j = 1; j <= len2; j++)
{
if (a[i - 1] == b[j - 1])
f[i][j] = f[i - 1][j - 1] + 1;
else
f[i][j] = max(f[i - 1][j], f[i][j - 1]); //动态规划
}
}
cout << f[len1][len2];
return 0;
}