2 3 1 2 3 3 2 1 6 1 5 3 2 6 4 3 6 2 4 5 1
2 4
/************************************************************************/
附上该题对应的中文题
你有两个序列{a1,a2,...,an}和{b1,b2,...,bn}. 他们都是1到n的一个排列. 你需要找到另一个排列{p1,p2,...,pn}, 使得序列{ap1,ap2,...,apn}和{bp1,bp2,...,bpn}的最长公共子序列的长度最大.
输入有多组数据, 第一行有一个整数T表示测试数据的组数. 对于每组数据: 第一行包含一个整数n(1≤n≤105), 表示排列的长度. 第2行包含n个整数a1,a2,...,an. 第3行包含n个整数 b1,b2,...,bn. 数据中所有n的和不超过2×106.
对于每组数据, 输出LCS的长度.
2 3 1 2 3 3 2 1 6 1 5 3 2 6 4 3 6 2 4 5 1
2 4
出题人的解题思路:
题目中给出的是两个排列, 于是我们我们可以先把排列分成若干个环, 显然环与环之间是独立的. 事实上对于一个长度为l(l>1)的环, 我们总可以得到一个长度为l−1的LCS, 于是这个题的答案就很明显了, 就是n减去长度大于1的环的数目.
首先,我们要搞清楚一个长度为L(L>1)的环,可以得到长度为L-1的最长公共子序列#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 100005; const int inf = 1000000000; const int mod = 2009; struct node { int a,b; }s[N]; bool cmp(node x,node y) { return x.a<y.a; } bool v[N]; int main() { int t,i,n,p,l,ans; scanf("%d",&t); while(t--) { memset(v,false,sizeof(v)); scanf("%d",&n); ans=0; for(i=1;i<=n;i++) scanf("%d",&s[i].a); for(i=1;i<=n;i++) scanf("%d",&s[i].b); sort(s+1,s+n+1,cmp); for(i=1;i<=n;i++) if(!v[i]) { p=i,l=1; while(s[p].b!=i) l++,p=s[p].b,v[p]=true; v[i]=true; //printf("#%d %d#\n",i,l); ans+=l>1?l-1:1; } printf("%d\n",ans); } return 0; }菜鸟成长记