LCS
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
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 n integers b1,b2,...,bn .
The sum of n in the test cases will not exceed 2×106 .
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 n integers 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
出题人的解题思路:
Problem 1. LCS
题目中给出的是两个排列, 于是我们我们可以先把排列分成若干个环, 显然环与环之间是独立的. 事实上对于一个长度为l(l>1)的环, 我们总可以得到一个长度为l−1的LCS, 于是这个题的答案就很明显了, 就是n减去长度大于
1的环的数目.
其实就是把数组a到b看成一条边,由于都是1~n,所以判断有多少个独立环,长度为一的时候特判,大于一的时候为l-1;
ps: 输入用scanf,用cin会超时;
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
struct node
{
int a,b;
}data[100005];
int cmp(const node &s1,const node &s2)
{
return s1.a<s2.a;
}
int main()
{
int vis[100005];
int t;
cin>>t;
while(t--)
{ int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&data[i].a);
for(int j=1;j<=n;j++)
scanf("%d",&data[j].b);
sort(data+1,data+n+1,cmp);
memset(vis,0,sizeof(vis));
int ans=0;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
int p=i,l=1;
while(data[p].b!=i)
{
l++;
p=data[p].b;
vis[p]=1;
}
vis[i]=1;
if(l==1) ans+=l;
else
ans+=(l-1);
}
}
cout<<ans<<endl;
}
return 0;
}