O(n*m)作法
dp[i][j]表示 a串取i个,b串取j个元素 所能得到的最长公共的子序列
dp的思想是运用i-1或j-1的经验,推出后续的最优答案。循环到dp[n][m]可得到最大值
思路:
如果a的第i个元素和b的第j个元素相等,那么dp[i][j]=dp[i][j-1] 可以得知此时dp[i][j]一定是优于dp[i-1][j]的,因为长度i-1是长度i的子串。
如果不相等呢?dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 意思是该元素在此刻没有用处,取a数组前i-1个元素和b数组前j个元素或a数组前i个元素和b数组前j-1个元素,也就是当前i,j 前一个状态的最大值
#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
int a[N], b[N];
int dp[N][N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (a[i] == b[j])
dp[i][j] = dp[i - 1][j] + 1;
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
cout << dp[n][n];
}