(luogu)[模板]最长公共子序列

给出1-n的两个排列P1和P2,求它们的最长公共子序列。

输入输出格式

输入格式:

第一行是一个数n,

接下来两行,每行为n个数,为自然数1-n的一个排列。

输出格式:

一个数,即最长公共子序列的长度

普通求最长公共子序列的dp[i][j]的方法肯定不行

但这里每个元素的值都是确定的了......

以f[i]表示i长度为i的最长公共子序列的最后一个元素在a和b数组中靠后的那一个的位置,这样贪心肯定是不对的

所以......

记录每个元素在a中的位置,所以这是一个{1,2,......,n}的双射

把b中的元素换成它在a中的位置,只要求一个最长上升子序列就可以了

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=1e5+7;
 5 int n,ans,l,r,mid;
 6 int a[maxn],b[maxn],tmp[maxn],f[maxn];
 7 int main(){
 8   cin>>n;
 9   for(int i=1;i<=n;i++) cin>>a[i],tmp[a[i]]=i;
10   for(int i=1;i<=n;i++) cin>>b[i],b[i]=tmp[b[i]];
11   for(int i=1;i<=n;i++){
12     if(b[i]>f[ans]) f[++ans]=b[i];
13     else{
14       l=0,r=ans;
15       while(l<=r){
16         mid=(l+r)/2;
17         if(b[i]>f[mid])l=mid+1;
18         else r=mid-1; 
19       }
20       f[l]=b[i];
21     }
22   }
23   cout<<ans<<endl;
24   return 0;
25 } 
原文地址:https://www.cnblogs.com/lcan/p/9790705.html