传送门
题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:第一行是一个数n,接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:一个数,即最长公共子序列的长度
输入输出样例
输入样例:
5
3 2 1 4 5
1 2 3 4 5
输出样例:
3
说明
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
题解
用 二分法求LIS求最长公共子序列(LCS)。
我们定义a[i]为P2排列中第i个数在P1排列中的位置。
由于最长公共子序列是向后比对的,则如果a[i]是递增的,就说明这一段在P1和P2中的位置都偏后,可以考虑纳入LCS。
则问题就变为求a数组的LIS。
Code:
#include<cstdio>
#include<cstdlib>
int a[100010],b[100010],f[100010];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
b[x]=i;
}
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
a[i]=b[x];
}
int len=1;
f[1]=a[1];
for(int i=2;i<=n;i++)
{
if(f[len]<a[i]) f[++len]=a[i];
else
{
int mid,l=1,r=len;
while(l<r)
{
mid=(l+r)/2;
if(f[mid]>a[i]) r=mid;
else l=mid+1;
}
if(f[l]>a[i]) f[l]=a[i];
}
}
printf("%d",len);
}
该博客讨论了如何解决洛谷P1439题,即找到两个排列的最长公共子序列(LCS)。通过二分法求解LIS(最长递增子序列)来找到P2排列中每个数在P1排列中的位置,然后计算这些位置的LIS以确定LCS。博客提供了问题描述、输入输出格式、样例及代码实现。

2320

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



