题目链接:https://www.luogu.org/problem/P1439
题意:给出n个数的两个排列a,b,求出两者最长公共子序列
因为都是n个数的排列,所以两者只是数的位置不同
用m数组记录a中每个数的位置,用ans数值来记录公共子序列每个数在a中的小标,通过遍历b数组,比较b数组中的 数在a中对应的位置和ans数组当前结尾数位置即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+7; const int inf=0x3f3f3f3f; const int N=1e7; const ll mod=998244353; #define meminf(a) memset(a,0x3f,sizeof(a)) #define mem0(a) memset(a,0,sizeof(a)) int n,a[maxn],b[maxn],m[maxn],ans[maxn],len=0; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]);m[a[i]]=i; } for(int i=1;i<=n;i++){ scanf("%d",&b[i]);ans[i]=inf; } for(int i=1;i<=n;i++){ if(m[b[i]]>ans[len]) ans[++len]=m[b[i]]; else { int l=0,r=len; //找第一个大于m[b[i]]的f的位置,进行更新,选更小的 //因为公共序列前面的越小,则将来就能取到更多的公共序列 while(l<r){ int mid=(l+r)>>1; if(ans[mid]>m[b[i]])r=mid; else l=mid+1; } ans[l]=min(ans[l],m[b[i]]); } } printf("%d ",len); return 0; }