题目描述:
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
题解:
此题要求O(nlogn)解决LCS。
我们考虑LCS转LIS,二分维护。
我们保证一个序列是单调的,那么将另一个序列按照标号排序,会发现转换后的LIS就是原序列的LCS。
但是这种解法有一个限制——两个排列要求是1~n的。
附上代码:
#include<cstdio> int a[100001],a1[100001],c[100001],n,b[100001],d[100001],l,cnt,len,idx,ans; int find(int l,int r,int x) { while(l<r) { int mid=(l+r)/2; if(d[mid]>=x) r=mid; else l=mid+1; } return l; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d",&b[i]); a1[b[i]]=i; } for(int i=1;i<=n;++i) { scanf("%d",&c[i]); a[i]=a1[c[i]]; } for(int i=1;i<=n;++i) { idx=find(1,len+1,a[i]); if(idx>len) ++len; d[idx]=a[i]; } printf("%d",len); }