题目描述
熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目。
小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们研究最长公共上升子序列了。
小沐沐说,对于两个数列 A和 B,如果它们都包含一段位置不一定连续的数,且数值是严格递增的,那么称这一段数是两个数列的公共上升子序列,而所有的公共上升子序列中最长的就是最长公共上升子序列了。
奶牛半懂不懂,小沐沐要你来告诉奶牛什么是最长公共上升子序列。
不过,只要告诉奶牛它的长度就可以了。
数列 A 和 B 的长度均不超过 3000。
样例
输入
4
2 2 1 3
2 1 2 3
输出
2
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 3010;
int n;
int a[2][N];
int f[N][N];
int maxn;
int main()
{
scanf("%d", &n);
for (int j = 0; j <= 1; j ++)
for (int i = 1; i <= n; i++)
scanf("%d", &a[j][i]);
int len = 0;
for (int i = 1; i <= n; i++)//枚举第一行数
{
int len = 0;
for (int j = 1; j <= n; j++)//枚举第二行数
{
f[i][j] = f[i - 1][j];//指范围, j指实际位置,指在1-i的范围,以j结尾的最长公共上升子序列长度。继承i-1情况
if (a[0][i] == a[1][j]) f[i][j] = max(f[i][j], len + 1);
//i,j指具体数据,当其相等,是公共子序列时,其数值为之前最长的且可接上a[i][0]的最大值。以i为主。
if (a[0][i] > a[1][j]) len = max(len, f[i - 1][j]);
//以比a[0][i]小的数结尾的最长公共上升子序列
}
}
int res = 0;
for (int i = 1; i <= n; i++)
res = max(res, f[n][i]);
printf("%d\n", res);
}
if (a[0][i] == a[1][j]) f[i][j] = max(f[i][j], len + 1);
可改为f[i][j] = len + 1;因为不可能出现f[i - 1][j] 大于len+1的情况,至多相等