题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入输出格式
输入格式:
第一行是一个数n,
接下来两行,每行为n个数,为自然数1-n的一个排列。
输出格式:
一个数,即最长公共子序列的长度
说明
【数据规模】
对于50%的数据,n≤1000
对于100%的数据,n≤100000
题目解析
因为是给定的两串数字是排列,所以可以利用一下排列的性质。
思考一下,如果两串数字中有一串是形如1 2 3 4 5 .....的,那么这个题的难度会大大降低,转变为求另一个串中的最长不下降子序列。
最长不下降子序列可以用nlogn的时间求出,这样就可以卡进时限了。
又发现数字的排列方式对本题影响不大,所以我们离散化一下,把第一个串强行离散成1 2 3 4 5 ......等于把每个数字映射一下,然后nlogn就可以了
Code
#include<iostream> #include<cstdio> using namespace std; const int MAXN = 100005; int n,len; int a[MAXN],b[MAXN]; int id[MAXN],dp[MAXN],d[MAXN]; int main() { scanf("%d",&n); for(int i = 1;i <= n;i++) { scanf("%d",&a[i]); id[a[i]] = i; } for(int i = 1;i <= n;i++) { scanf("%d",&b[i]); } int tmp; for(int i = 1;i <= n;i++) { if(id[b[i]] > d[len]) { d[++len] = id[b[i]]; dp[i] = len; continue; } tmp = lower_bound(d + 1,d + 1 + len,id[b[i]]) - d; d[tmp] = id[b[i]]; dp[i] = tmp; } printf("%d ",len); }