Glory and LCS
时间限制: 1 Sec 内存限制:128 MB
提交: 217 解决: 48
题目描述
大家都知道,Glory不但知识水平高,并且非常喜欢思考,有一天Glory在思考一个问题,他在纸上写了两个1到n的排列,并且他想知道这两个排列的最大公共子序列的长度是多少,当然像Glory这么优秀的人当然一眼就看出了这个题目的答案,但是他太忙了,不想打这个代码,于是他扔给了他的小弟,但是他的小弟知识水平不够,所以他想找你萌帮帮他,你萌能帮他解决这个问题吗。
输入
第一行一个数T,表示数据的测试组数(T<=5)
每组数据一个n,表示排列的长度(1<= n <= 1e5)
接下来两行,每行一个1~n的排列
输出
对于每组数据,输出一个数表示最长公共子序列的长度。
样例输入
2
2
1 2
1 2
3
1 3 2
2 3 1
样例输出
2
1
由于是排列所以每个元素只出现一次。我们可以记录下来每个数 p 在第一个排列中出现的位置a[p] = i,在读第二个数列的时候把第二个排列中每个数 p 在第一个排列中出现的位置依次存在 b[] 中,即b[i] = a[p]。则 b[](位置序号)中的上升子序列对应的元素序列均为第一个排列的子序列,求 b[] 的最长上升子序列即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
usingnamespace std;
const int maxn = 1e5 + 5;
int a[maxn],b[maxn],c[maxn];
int main()
{
int t,n,p;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 1;i <= n; ++i)
{
scanf("%d",&p);
a[p] = i;
}
for(int i = 1;i <= n; ++i)
{
scanf("%d",&p);
b[i] = a[p];
}
int len = 1,j;
c[0] = 0;
for(int i = 1;i <= n; ++i)
{
j = lower_bound(c,c + len,b[i]) - c;
if(j == len) ++len;
c[j] = b[i];
}
printf("%d\n",len - 1);
}
return 0;
}
Godv的数列
时间限制: 3 Sec 内存限制: 128 MB<