题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入格式:
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:
一个数,即最长公共子序列的长度
输入输出样例
输入样例#1:
5
3 2 1 4 5
1 2 3 4 5
输出样例#1:
3
题解
这题名字叫最长公共子序列,实际上是最长单调上升子序列的一个推广
因为本人并不能分清LIS和LCS 基于A,B都是排列数,将b在a的位置标记,即p[b[i]]=a[i];
因为数据较大,需要使用nlogn的算法,可以用STL的二分查找
code
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100005;
int dp[N],p[N],a[N],b[N],f[N];
bool cmp(int a,int b)
{
return a<b;
}
int main()
{
//freopen("t1.in","r",stdin);
//freopen("t1.out","w",stdout);
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
for(i=1;i<=n;i++)
f[a[i]]=i;
for(i=1;i<=n;i++)
p[i]=f[b[i]];
int ans=0;
for(i=1;i<=n;i++)
{
if(p[i]>dp[ans])
dp[++ans]=p[i];
else
if(p[i]<dp[ans])
dp[lower_bound(dp+1,dp+ans+1,p[i])-dp]=p[i];
}
printf("%d\n",ans);
return 0;
}
后面可能还会有真正的各种模板大杂烩,敬请期待!