专栏文章

题解:P1439 【模板】最长公共子序列

P1439题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipxzs1i
此快照首次捕获于
2025/12/03 19:47
3 个月前
此快照最后确认于
2025/12/03 19:47
3 个月前
查看原文

题目大意

给定 11nn 的两种排列,求两种排列下的最长公共子序列的长度。

解题思路

本题乍看是最长公共子序列的模板,但是数据范围会超空间和时间。再看题目给定的序列是 11nn 的排列,即在序列一中存在的元素必然在序列二中存在。
分析问题发现如果我们对序列一中的第 ii 个数 aia_i 映射为 ii。这样序列一就是升序序列。考虑对于序列一中每一个数都在序列二中存在,那么只需要找到序列二映射后的元素的最长升序序列即可找到答案。
这样本题的做法转换成了求最长上升子序列,需要效率为 O(nlogn)O(n\log{n}) 的算法。
C
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e5+5;
int a[N], b[N], mp[N], dp[N];
int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		mp[a[i]] = i;
	}
	for (int i = 1; i <= n; i++)
		scanf("%d", &b[i]);
	int len = 1;
	dp[1] = mp[b[1]];
	for (int i = 2; i <= n; i++) {
		if (dp[len] < mp[b[i]]) {
			dp[++len] = mp[b[i]];
		} else {
			int x = lower_bound(dp + 1, dp + 1 + len, mp[b[i]]) - dp;
			dp[x] = mp[b[i]];
		}
	}
	cout << len;
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...