Problem Description
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.
Input
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.
Output
For each test case, output the maximum length of LCS.
Sample Input
2 3 1 2 3 3 2 1 6 1 5 3 2 6 4 3 6 2 4 5 1
Sample Output
2 4
Source
题意:
给出1~n的两个排序a[n],b[n],求用某个排序p[n],使得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的环的数目.
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 #include <stack> 15 using namespace std; 16 #define PI acos(-1.0) 17 #define max(a,b) (a) > (b) ? (a) : (b) 18 #define min(a,b) (a) < (b) ? (a) : (b) 19 #define ll long long 20 #define eps 1e-10 21 #define MOD 1000000007 22 #define N 100006 23 #define inf 1e12 24 int n; 25 int a[N]; 26 int b[N]; 27 int vis[N]; 28 bool dfs(int x){ 29 int tmp=b[x]; 30 if(!vis[tmp]){ 31 vis[tmp]=1; 32 dfs(a[tmp]); 33 return true; 34 } 35 return false; 36 } 37 int main() 38 { 39 int t; 40 scanf("%d",&t); 41 while(t--){ 42 memset(vis,0,sizeof(vis)); 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++){ 45 scanf("%d",&a[i]); 46 } 47 int x; 48 for(int i=1;i<=n;i++){ 49 scanf("%d",&x); 50 b[x]=i; 51 } 52 int ans=0; 53 54 for(int i=1;i<=n;i++){ 55 if(!vis[i]){ 56 vis[i]=1; 57 if(!dfs(a[i])){ 58 ans--; 59 } 60 ans++; 61 } 62 } 63 printf("%d ",n-ans); 64 } 65 return 0; 66 }