题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:
一个数,即最长公共子序列的长度
输入输出样例
说明
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
****复杂度为nlogn哦,离散化,然后求最长上升序列
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 int i,j,n,a[100005],b[100005],ans,c[100005],f[100005]; 7 int main() 8 { 9 scanf("%d",&n); 10 for(i = 1;i <= n;i++) 11 { 12 scanf("%d",&a[i]); 13 c[a[i]] = i; //用于离散化 14 } 15 for(i = 1;i <= n;i++) 16 { 17 scanf("%d",&b[i]); 18 f[i] = 0x7ffffff; 19 } 20 f[0] = 0; 21 ans = 0; 22 for(i = 1;i <= n;i++) 23 { 24 int l = 0,r = ans,mid; 25 if(c[b[i]] > f[ans]) //求最大上升子序列 26 { 27 ans++; 28 f[ans] = c[b[i]]; 29 } 30 else 31 { 32 while(l < r) 33 { 34 mid = (l + r) / 2; 35 if(f[mid] > c[b[i]]) 36 r = mid; 37 else 38 l = mid + 1; 39 } 40 f[l] = min(f[l],c[b[i]]); // 求最大上升子序列长度为l时的最后一个值越小越好 41 } 42 } 43 printf("%d",ans); 44 return 0; 45 }