洛谷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

****复杂度为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 }
原文地址:https://www.cnblogs.com/rax-/p/9934249.html