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

举报
辰chen 发表于 2022/06/19 23:46:39 2022/06/19
【摘要】 P1439 【模板】最长公共子序列 P1439 【模板】最长公共子序列AC代码 P1439 【模板】最长公共子序列 本题链接:P1439 【模板】最长公共子序列 本博客给出本题截图:...

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


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

本题链接:P1439 【模板】最长公共子序列

本博客给出本题截图
在这里插入图片描述

AC代码

代码解释
本题其实是一个 LIS 问题
二维状态量的话显然会TLE,这个题和其他的最长公共子序列不同的一点就是它只会包涵并且肯定包涵1 ~ n这些数,相当于P1数组和P2数组中的元素都是唯一对应,这里我们这样去处理:

我们把数组P1中的元素看成是一种顺序,那么本题要求的其实就变成了数组P2在数组P1的这种顺序下的最长上升子序列的长度,因为我们把P1数组看成了顺序,那么P2数组肯定就是单调上升的,那么P2数组中按照P1数组的排列方式下的上升子序列就是公共子序列

拿样例去举例说明:
例子中 P1数组:3 2 1 4 5,P2数组:1 2 3 4 5,我们设定a数组中的元素对应关系:3对应a,2对应b,1对应c,4对应d,5对应e,那么我们的P1数组就会变成:a b c d e,这就是一种新的顺序,那么P2数组就变成了:c b a d e,这就是P2数组在P1数组的顺序中的排列,故P1数组肯定满足单调上升,所以我们只要把P2数组中的最长上升子序列找出来,这个子序列的长度就是我们要求的最长公共子序列。

如何把P1数组设成我们的顺序呢:离散化思维去处理即可

代码

#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100010;

int b[N];
int p[N];
int f[N];
int n;

bool cmp(int u, int k)
{
	if (p[u] < p[k]) return true;
	return false;
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i ++ )
	{
		int x;
		scanf("%d", &x);
		p[x] = i;
	}
	for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
	
	int len = 0;
	for (int i = 1; i <= n; i ++ )
	{
		if (p[f[len]] < p[b[i]]) 
			f[++ len] = b[i];
		else 
		{
			int k = upper_bound(f + 1, f + len + 1, b[i], cmp) - f;
			f[k] = b[i];
		}
	}
	
	printf("%d\n", len);
	
	return 0;
}

文章来源: chen-ac.blog.csdn.net,作者:辰chen,版权归原作者所有,如需转载,请联系作者。

原文链接:chen-ac.blog.csdn.net/article/details/119829604

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。