a[N]:序列a
b[N]:序列b
f[i][j]:a序列前i个字母 与 b序列前j个字母 的最长公共子序列的长度
集合划分:
- 没有a[i] b[j]
max=f[i−1][j−1] - 有a[i],没b[j]:a[i]不出现在子序列当中,b[j]一定出现在子序列当中
不能直接用f[i-1][j]来表示,因为表示的是在a序列的前i-1个字母中出现,并且在b的前j个字母中出现 - 没a[i],有b[j]
- 有a[i],有b[j]
max=f[i−1][j−1]+1max=f[i−1][j−1]+1
实际上,在计算时,①包含在②和③的情况中,所以①不用考虑
#include <iostream>
using namespace std;
const int N = 1010;
int n , m;
char a[N] , b[N];
int f[N][N];
int main()
{
cin >> n >> m;
cin >> a + 1 >> b + 1;
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
{
f[i][j] = max(f[i - 1][j] , f[i][j - 1]);//②和③的情况一定存在,所以可以无条件优先判断
if(a[i] == b[j]) f[i][j] = max(f[i][j] , f[i - 1][j - 1] + 1);
}
cout << f[n][m] << endl;
return 0;
}