题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:
一个数,即最长公共子序列的长度
输入输出样例
说明
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
【题解】
首先不难想到的是将其转化成一个序列的最长上升子序列
由于两个序列均为1~n的排列,在将其中一个序列的元素换成该元素在另一序列中的下标时,最长公共子序列即可写成一个最长上升子序列,其中每一项的值为在其中一个序列中的下标(由观察样例不难发现 因为样例给了一个序列为1 2 3 4 5,替换的想法较为明显)
然后就可以二分地做到O(nlogn)
1 //luogu P1439 2 int n; 3 int a[111111],b[111111]; 4 int dy[111111]; 5 int f[111111]; 6 int ans; 7 8 int main(){ 9 n=read(); 10 for(int i=1;i<=n;i++) a[i]=read(),dy[a[i]]=i; 11 for(int i=1;i<=n;i++) b[i]=read(),b[i]=dy[b[i]]; 12 13 for(int i=1;i<=n;i++){ 14 if(b[i]>f[ans]){ 15 ans++; 16 f[ans]=b[i]; 17 } 18 else{ 19 f[lower_bound(f+1,f+ans+1,b[i])-f]=b[i]; 20 } 21 } 22 23 print(ans); 24 return 0; 25 }