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; }