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;
}

 

原文链接: https://www.cnblogs.com/Willette/p/17065569.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    LCS(最长公共子序列)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/313705

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 下午1:00
下一篇 2023年2月16日 下午1:01

相关推荐