最长公共子序列
测试样例
样例输入
5 5
3 2 1 4 5
1 2 3 4 5
样例输出
3
数据规模
对于 100% 的数据, 1 ≤ n , m ≤ 5000 , 1 ≤ a i , b i ≤ 1 0 4 1≤n,m≤5000,1≤a_i,b_i≤10^4 1≤n,m≤5000,1≤ai,bi≤104
dp数组是二维的,其中 dp[i][j] 的意义是在 a[i] 和 b[j] 前最长公共子串的长度(a、b是给定的两个原数组)
其实这题想要警醒的是下标的设置,因为会有 dp[i - 1][j - 1] 这种迭代中出现的变量,为了防止数组下标越界,所以要把原数组的首个值的下标设置为从 1 开始。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[10000000] = {0};
ll b[10000000] = {0};
ll dp[6000][6000] = {0};
int main()
{
ll n, m;
cin >> n >> m;
for (ll i = 1; i <= n; i++)//要从下标为1开始存,否则在下面dp的时候可能会出现越界或没有把a[0]/b[0]计算进去
cin >> a[i];
for (ll i = 1; i <= m; i++)
cin >> b[i];
dp[0][0] = dp[1][0] = dp[0][1] = 0;
for(ll i = 1;i < n;i ++)//注意不要越界
{
for(ll j = 1;j < m;j ++)
{
if(a[i] == b[j])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i][j - 1],dp[i - 1][j]);
}
}
cout << dp[n - 1][m - 1];
return 0;
}