给定两个长度分别为 N
和 M
的字符串 A
和 B
,求既是 A
的子序列又是 B
的子序列的字符串长度最长是多少。
输入格式
第一行包含两个整数 N
和 M
。
第二行包含一个长度为 N
的字符串,表示字符串 A
。
第三行包含一个长度为 M
的字符串,表示字符串 B
。
字符串均由小写字母构成。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N,M≤1000
输入样例:
4 5
acbd
abedc
输出样例:
3
// 数据是两个数组,但dp函数是二维矩阵
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
char a[N], b[N];
int f[N][N]; // f[i][j]的含义为在a的前i,b的前j个字母中,最大公共子序列的长度
// 将f[i][j]的集合分为四部分,1:不选a[i]和b[j] 2: 选a[i]不选b[j] 3: 选b[j]不选a[i] 4: 都选
// 1的结果为f[i - 1][j - 1] (2和3的结果包含了1)
// 2的结果为f[i - 1][j] (这个结果包括了2,但又在f[i][j]之内)
// 3的结果为f[i][j - 1] (这个结果包括了3,但又在f[i][j]之内)
// 4的结果为f[i - 1][j - 1] (其中需要满足a[i] == b[j])
// 由于本题求的是最大值所以2和3的结果也符合题意(虽然2和3的区间存在交集)
int main()
{
cin >> n >> m;
cin >> (a + 1) >> (b + 1);
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
if (a[i] == b[j]) f[i][j] = max(f[i][j], f[i -1][j - 1] + 1);
else f[i][j] = max(f[i - 1][j], f[i][j - 1]);
cout << f[n][m];
return 0;
}