题目描述
给出 1,2,…,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列。
输入格式
第一行是一个数 n。
接下来两行,每行为 n 个数,为自然数 1,2,…,n 的一个排列。
输出格式
一个数,即最长公共子序列的长度。
输入输出样例
输入 #1复制
5 3 2 1 4 5 1 2 3 4 5
输出 #1复制
3
说明/提示
- 对于 50% 的数据, n≤103;
- 对于 100% 的数据, n≤105。
代码实现:
#include <iostream>
#include <vector>
#include <algorithm> // 确保包含此头文件以使用lower_bound
using namespace std;
int main() {
int n;
scanf("%d", &n);
// 读取第一个排列并记录每个元素的位置
vector<int> P1(n);
vector<int> pos1(n + 1); // pos1[x]表示x在P1中的位置
for (int i = 0; i < n; ++i) {
scanf("%d", &P1[i]);
pos1[P1[i]] = i;
}
// 读取第二个排列并转换为位置序列
vector<int> A(n);
int x;
for (int i = 0; i < n; ++i) {
scanf("%d", &x);
A[i] = pos1[x];
}
// 求转换后序列的最长递增子序列长度
vector<int> tails;
for (int i = 0; i < n; ++i) {
int num = A[i];
// 显式指定迭代器类型,避免可能的类型推导问题
vector<int>::iterator it = lower_bound(tails.begin(), tails.end(), num);
if (it == tails.end()) {
tails.push_back(num);
} else {
*it = num;
}
}
printf("%d\n", (int)tails.size());
return 0;
}
676

被折叠的 条评论
为什么被折叠?



