最长公共子序列
最长公共子序列
给定两个长度分别为
试求出最长的公共子序列。
做法
我们考虑进行动态规划
设
那么我们最终的答案就是
考虑如何转移,我们分情况来讨论。
当
否则
同时我们考虑继承前面的答案,即
不难发现
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]==b[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1)
}
}
还是挺好理解的qwq
但是,我们怎么得到
也是用一个二维数组
在对应字符相等的时候,用↖标记
在
在
伪代码:
若想得到
如果箭头是↖,则代表这个字符是 i--,j--
如果箭头是←,则代表这个字符不是 j--
如果箭头是↑ ,也代表这个字符不是 i--
如此直到
做法
最长上升子序列
我们通过一个
因为最长公共子序列是按位向后比对的,所以
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int a[N],b[N],n,m,ans;
unordered_map<int,int> mp;//映射关系
int dp[N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),mp[a[i]]=i;
for(int i=1;i<=m;i++) scanf("%d",&b[i]),b[i]=mp[b[i]];
memset(dp,0x3f,sizeof(dp));
dp[1]=b[1];
ans=1;
for(int i=2;i<=m;i++){
if(b[i]>dp[ans]) {dp[++ans]=b[i];continue;}
int l=1,r=ans,res=0;
while(l<=r){
int mid=(l+r)>>1;
if(dp[mid]<b[i]){
res=mid;
l=mid+1;
}else{
r=mid-1;
}
}
dp[res+1]=min(dp[res+1],b[i]);
}
cout<<ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】