P1439 【模板】最长公共子序列
题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入格式
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式
一个数,即最长公共子序列的长度
输入输出样例
输入 #1复制
5
3 2 1 4 5
1 2 3 4 5
输出 #1复制
3
说明/提示
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
与最长递增子序列的想法大同小异
通过标记来选择
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,a[maxn],b[maxn],mmap[maxn],f[maxn];
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i];
mmap[a[i]]=i;//标记a出现的位置
}
for(int i=1; i<=n; i++)
{
cin>>b[i];
f[i]=0x3f3f3f3f;//初始化f
}
int len=0;
f[0]=0;
for(int i=1; i<=n; i++)
{
int l=0,r=len,mid;
if(f[len]<mmap[b[i]]) f[++len]=mmap[b[i]];// 如果b数组在a的位置大于末尾的数 就把b数组加进去
else
{
while(l<r)
{
mid=(l+r)/2;
if(f[mid]>mmap[b[i]]) r=mid;
else l=mid+1;
}//二分查找 找到b在f中的位置 选择替换它
f[l]=mmap[b[i]];//替换它
}
}
cout<<len<<endl;
return 0;
}