LCSTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 23 Accepted Submission(s): 12
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
Sample Output
|
题意:给两个由1~n组成的n个数序列a[]和b[],让你找到一个1~n的序列p[],使得a[p[1]] , a[p[2]] ... a[p[n]] 和 b[p[1]], b[p[2]]... b[p[3]]的LCS最大,输出最大的LCS。
分析:对于一个有n个元素的置换群,我们可以付出一个元素的代价得到n-1长度的LCS。
思路:统计元素个数大于1的置换群个数ans,答案就是 n - ans。为了方便可以用pos[i]记录a或b序列中元素i所在的位置。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100000+10
using namespace std;
struct rec
{
int a, b;
};
rec num[MAXN];
bool vis[MAXN];
int pos[MAXN];
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d", &num[i].a);
pos[num[i].a] = i;
}
//int cnt = 0;
for(int i = 0; i < n; i++)
{
scanf("%d", &num[i].b);
// if(num[i].a == num[i].b)
// cnt++;
}
memset(vis, false, sizeof(vis));
int ans = 0;
for(int i = 0; i < n; i++)
{
if(vis[num[i].a]) continue;
int j = num[i].b;
int have = 1;
while(j != num[i].a)
{
vis[j] = true;
int next = pos[j];
have++;
j = num[next].b;
}
ans += have > 1 ? 1 : 0;
//ans = max(have, ans);
}
printf("%d\n", n-ans);
}
return 0;
}