2334: 【提高】最长公共子序列(LCS)(2)
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:1
解决:1
题目描述
给出 的两个排列 和 ,求它们的最长公共子序列。
和最长公共子序列(LCS)(1)问题不同的是,本题的 在 之间。
输入
第一行是一个数 ;( 是 之间的整数)
接下来两行,每行为 个数,为自然数 的一个排列( 的排列每行的数据都是 之间的数,但顺序可能不同,比如 的排列可以是: ,也可以是 )。
输出
一个整数,即最长公共子序列的长度。
样例输入 复制
5
3 2 1 4 5
1 2 3 4 5
样例输出 复制
3
提示
数据范围
对于 的数据,;
对于 的数据,。
#include<bits/stdc++.h>
using namespace std;
const int N = 100100;
int a[N], b[N], c[N], dp[N];
int n, i;
int main() {
cin >> n;
for (i = 1; i <= n; i++) {
scanf("%d", & a[i]);
c[a[i]] = i; //求出a数组的每个数的位置
}
for (i = 1; i <= n; i++) scanf("%d", & b[i]);
//求b数组的每个数在a数组的位置(c[b[i]])的 LIS
dp[1] = c[b[1]];
//边界
int len = 1;
int l, r, mid; //从第2个数开始讨论
for (i = 2; i <= n; i++) { //增加 LIS的长度
if (c[b[i]] > dp[len]) {
len++;
dp[len] = c[b[i]];
} else {
l = 1;
r = len;
while (l <= r) {
mid = (l + r) / 2;
if (c[b[i]] <= dp[mid]) r = mid - 1;
else l = mid + 1;
}
dp[l] = c[b[i]];
}
}
cout << len;
return 0;
}