1233: Glory and LCS
时间限制: 1 Sec 内存限制: 128 MB提交: 256 解决: 61
[ 提交][ 状态][ 讨论版]
题目描述
大家都知道,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
思路:LCS转为LIS,具体思路可以参考
https://blog.csdn.net/qkoqhh/article/details/78143809这位大牛的代码,其实就是求记录位置的数组的LIS,当然了,要用它的nlogn算法~
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define INF 1000000000
using namespace std;
int a[100010];
int b[100010];
int mp[100010];
int ind[100010];
int dp[100010];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(mp,0,sizeof(mp));
memset(ind,0,sizeof(ind));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
mp[b[i]]=i;
}
for(int i=1;i<=n;i++)
ind[i]=mp[a[i]];
fill(dp,dp+n+1,INF);
for(int i=1;i<=n;i++)
*lower_bound(dp+1,dp+n+1,ind[i])=ind[i];
printf("%d\n",lower_bound(dp+1,dp+n+1,INF)-(dp+1));
}
return 0;
}