题意:
就是给你一个由n个数组成的由1~n的排列,首先是a数组,然后是b数组,然后你可以重新改变他们的顺序使之所形成的LCS是最长的,注意,这里改变是同时的,就是相当于a与b数组是被捆绑起来了一样。
思路:
想到了无论怎么改变,反正a[i]与b[i]的相对匹配方式是不会变的,所以我们只需要贪心的每次找到能够匹配a[i]的那个就可以了,这里用到了一个小技巧就是记录下a[i]的下标位置,每次记录下与当前a[i]相等的b[i]的位置,然后把它的位置与a[i+1]的位置去交换一下,然后标记b[i]已经是不能取了,因为我们是从前往后进行的,所以如果当前b[i]与a[i]没有匹配的话,那么它就没有机会去和其他的匹配了。
如果实在不懂的话,可以手模一下代码,然后就可以知道了。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 100010
int a[maxn],pos[maxn],b[maxn];
int vis[maxn];
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(pos,0,sizeof(pos));
memset(vis,0,sizeof(vis));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
scanf("%d",&b[i]);
pos[b[i]]=i;
}
int lmax=0;
for(int i=1;i<=n;i++){
if(a[i]==b[i]) lmax++;
else{
if(vis[a[i]]) continue;
int j=pos[a[i]];
pos[b[i+1]]=j;
swap(a[i+1],a[j]); swap(b[i+1],b[j]);
vis[b[i]]=1; //!!
lmax++;
}
}
printf("%d\n",lmax);
}
}