LCS(最长公共子序列)

P1439 【模板】最长公共子序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

A:3 2 1 4 5

B:1 2 3 4 5

 

思路:

 主要考虑离散化,先不离散化成数字,不好理解
A:3 2 1 4 5 → A:a b c d e
离散化之后A是单调递增的
举几个B的例子:× b × d ×   b,d是单调递增的,b,d是A,B的公共子序列之一
        a × c d × a,c,d是单调递增的,a,c,d是A,B的公共子序列之一,
题目样例来说
A: a b c d e
B: c b a d e   a,d /a,d,e都是递增的,都是A,B的公共子序列之一
显然这时候我们只用求离散化后,B的最长上升子序列,就是LCS的答案了
 
Code:
复制代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   //vector函数
#define popb pop_back  //vector函数
#define fi first
#define se second
const int N=1e5+10;
//const int M=;
//const int inf=0x3f3f3f3f;     //一般为int赋最大值,不用于memset中
//const ll INF=0x3ffffffffffff; //一般为ll赋最大值,不用于memset中
int T,n,a[N],b[N],c[N],pos[N],f[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) a[i]=read(),pos[a[i]]=i;
    for(int i=1;i<=n;i++) b[i]=read(),c[i]=pos[b[i]]; 将b数组离散化成c数组
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int l=1,r=ans;
        if(!ans) { ans=1,f[1]=c[1];continue; }
        while(l+1<r)
        {
            int mid=(l+r)/2;
            if(f[mid]<c[i]) l=mid;
            else r=mid;
        }
        int len;
        if(f[r]<c[i]) len=r;
        else if(f[l]<c[i]) len=l;
        else len=0;
        if(!f[len+1]) f[len+1]=c[i];
        else f[len+1]=min(f[len+1],c[i]);
        ans=max(ans,len+1);
    }
    printf("%d\n",ans);
    return 0;
}
复制代码

 

posted @   QAQ啥也不会  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示