hdu 5495 置换

来源:互联网 发布:mac幼圆字体下载 编辑:程序博客网 时间:2024/05/17 09:30

LCS

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 927    Accepted Submission(s): 520


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 integerT, indicating the number of test cases. For each test case:

The first line contains an integer n(1n105) - 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
231 2 33 2 161 5 3 2 6 43 6 2 4 5 1
 

Sample Output
24


题意:

给出两个1~n到全排列,问通过同一种置换,得到的两个序列的最长公共子序列最长

题解:

先在草稿上运算两个样例

因为两个序列要经过同一种置换,所以我们可以对第二个序列按照第一个序列进行置换

然后写出这个序列的循环节,发现ans等于所有循环节长度 L   的max(1,L-1)的和


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define maxn 100005int a[maxn],b[maxn],vis[maxn];int main(){int x,n,T;freopen("in.txt","r",stdin);scanf("%d",&T);while(T--){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i<=n;i++) scanf("%d",&x),b[a[i]]=x;int ans=0;memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++){if(vis[i]) continue;int p=i,cnt=0;do{p=b[p];vis[p]=1;cnt++;}while(p!=i);ans+=max(1,cnt-1);}printf("%d\n",ans);}return 0;}


原创粉丝点击