最长公共子序列

将第一个序列标号,所以序号和值就相互映射,再将第二个序列用映射转变一下,最后只要求转变后的序列的最长上升子序列就行了,求lis只要维护一个单调递增的栈,大于栈首就入栈,小于栈首就用二分查找替换最小的大与它的数
`#include

include

include

include<math.h>

using namespace std;

const int N=2e5+7;
int dp[N]={0};
int lst1[N],lst[N];

int erfen(int x,int r){
int l=0;
while(l<=r){
int m=(l+r)/2;
if(dp[m]<x){
l=m+1;
}
else r=m-1;
}
return l;
}

int main(){
int n,a,m=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a);
lst1[a]=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&a);
lst[i]=lst1[a];
}
int top=0;dp[0]=lst[1];
for(int i=2;i<=n;i++){
if(lst[i]>dp[top]){
top++;
dp[top]=lst[i];
}
else{
int p=erfen(lst[i],top);
dp[p]=lst[i];
}
}
printf("%d",top+1);
return 0;
}`

posted @ 2025-02-16 20:17  十柒*  阅读(0)  评论(0编辑  收藏  举报