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: 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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?