最长公共子序列i j分别表示前i个字符和前j个字符,而这里不能这样表示,为什么?
举例
设有两个字符串abcdf abcef
当i j都等于5时,dp[i][j] = dp[i - 1][j - 1] + 1
也就是dp[5][5] = dp[4][4] + 1
,此时前4个字符里最长连续公共子序列应该是abc
,但f
和abc
是不相连的,题目里要求是连续的子序列
状态表示
本题正确的状态表示是以i j结尾的子序列,那么当i j位置的字符相等时,就可以从dp[i - 1][j - 1]
转移过来,因为第i个字符一定和第i - 1个字符相连,同理,第j个字符一定和第j - 1个字符相连。当i j位置的字符不相等时,任何以i j结尾的连子序列都不匹配,也就是以i j结尾的连续子序列长度为0
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int dp[N][N];
int n, m;
string a, b;
int ans;
int main()
{
cin >> a >> b;
int n = a.size(), m = b.size(), t;
a = ' ' + a, b = ' ' + b;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
{
if(a[i] == b[j])
dp[i][j] = dp[i - 1][j - 1] + 1;
if(dp[i][j] >= ans)
{
ans = dp[i][j];
t = i;
}
}
cout << ans << endl;
for(int i = t - ans + 1; i <= t; i ++)
cout << a[i];
}