您的位置:首页 > 其它

hdu 5495 LCS

2015-10-05 21:56 253 查看
[align=left]Problem Description[/align]

You are given two sequence {a1,a2,...,an} and {b1,b2,...,bn}. Both sequences are permutation of {1,2,...,n}. You are going to find another permutation {p1,p2,...,pn} such that the length of LCS (longest common subsequence) of {ap1,ap2,...,apn} and {bp1,bp2,...,bpn} is maximum.


[align=left]Input[/align]

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n(1≤n≤105) - the length of the permutation. The second line contains n integers a1,a2,...,an. The third line contains nintegers b1,b2,...,bn.

The sum of n in the test cases will not exceed 2×106.


[align=left]Output[/align]

For each test case, output the maximum length of LCS.


[align=left]Sample Input[/align]

2
3
1 2 3
3 2 1
6
1 5 3 2 6 4
3 6 2 4 5 1


[align=left]Sample Output[/align]

2
4


[align=left]Source[/align]
BestCoder Round #58 (div.2)

题意:

给出1~n的两个排序a
,b
,求用某个排序p
,使得a[p[0]],a[p[1]],a[p[2]]······与b[p[0]],b[p[1]],b[p[2]]······的最长公共子序列取得最大值,求最终取得的LCS多大。

思路:

LCS一定会tle的,关键就是这是1~n的序列,所以必然a[],b[]存在相同的数字,也就是一定会由一些循环节组成,而每个循环节经过排列首尾相接一定会有只相错一位的情况,最终的LCS也就是总长减去循环节的个数,特判自环不减就行了。直接深搜写的,跑得比较慢。

来自官方题解:

题目中给出的是两个排列, 于是我们我们可以先把排列分成若干个环, 显然环与环之间是独立的. 事实上对于一个长度为l(l>1)的环, 我们总可以得到一个长度为l−1的LCS, 于是这个题的答案就很明显了, 就是n减去长度大于1的环的数目.

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<stdlib.h>
#include <stack>
using namespace std;
#define PI acos(-1.0)
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
#define ll long long
#define eps 1e-10
#define MOD 1000000007
#define N 100006
#define inf 1e12
int n;
int a
;
int b
;
int vis
;
bool dfs(int x){
int tmp=b[x];
if(!vis[tmp]){
vis[tmp]=1;
dfs(a[tmp]);
return true;
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int x;
for(int i=1;i<=n;i++){
scanf("%d",&x);
b[x]=i;
}
int ans=0;

for(int i=1;i<=n;i++){
if(!vis[i]){
vis[i]=1;
if(!dfs(a[i])){
ans--;
}
ans++;
}
}
printf("%d\n",n-ans);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: