xdoj1233

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

猜你喜欢

转载自blog.csdn.net/star_moon0309/article/details/80110261
今日推荐