最长上升子序列、最长公共子序列、最长公共上升子序列(LIS、LCS、LCIS)

news2024/12/23 2:06:51

LIS、LCS、LCIS

  • 最长上升子序列LIS
  • 最长公共子序列LCS
  • 最长公共上升子序列LCIS

最长上升子序列LIS

题目链接:AcWing895. 最长上升子序列
在这里插入图片描述
这里只说明 O ( n 2 ) O(n^2) O(n2)的解法, O ( n l o g n ) O(nlogn) O(nlogn)解法之前的博客有介绍
O ( n 2 ) O(n^2) O(n2)的解法较为容易理解

状态表示:
这里状态用一维表示,dp[i]表示以b[i]作为结尾的最长子序列的长度

状态转移:
遍历b[i]前的所有元素,找出最长的以b[i]结尾的最长子序列长度
for(int j=0;j<i;j++)
	if(b[j]<b[i]) dp[i]=max(dp[i],dp[j]+1)

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int b[N];
int dp[N];
int main(){
    int n,res=0;
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    b[0]=-0x3f3f3f3f;
    for(int i=1;i<=n;i++){
        for(int j=0;j<i;j++)
            if(b[i]>b[j]) dp[i]=max(dp[i],dp[j]+1);
        res=max(res,dp[i]);
    }
    cout<<res;
    return 0;
}

最长公共子序列LCS

题目链接:AcWing897. 最长公共子序列
在这里插入图片描述

状态表示:
状态用二维表示,dp[i][j]表示A[1~i],B[1~j]的最长公共子序列

状态转移:
if(A[i]==B[j]) dp[i][j]=dp[i-1][j-1]+1;//最长公共子序列增长一位
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);//从两种情况中选择长的一种传递

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]最长公共子序列
char A[N],B[N];
int main(){
    int n,m;
    cin>>n>>m;
    cin>>A+1>>B+1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(A[i]==B[j]) dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    cout<<dp[n][m];
    return 0;
}

最长公共上升子序列LCIS

AcWing272. 最长公共上升子序列
在这里插入图片描述
这里我们考虑将上面的LIS和LCS结合

状态表示:
状态用二维来表示
dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列

状态转移:
 if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];
 	else {
		int t=0;
		for(int k=1;k<j;k++)
			if(B[k]<B[j]) t=max(t,dp[i][k]);
	dp[i][j]=t+1;
}
当A[i]!=B[j]时,状态从dp[i-1][j]转移来
当A[i]==B[j]时,我们要考虑将B[j]前面求出的最长公共上升子序列中的哪个子序列之后,所以需要遍历前面所有的子序列(A[i]与B[1~k],k<j匹配的子序列)

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3010;
int A[N],B[N];
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&A[i]);
    for(int i=1;i<=n;i++) scanf("%d",&B[i]);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];
            else {
                int t=0;
                for(int k=1;k<j;k++)
                    if(B[k]<B[j]) t=max(t,dp[i][k]);
                dp[i][j]=t+1;
            }
    }
    int res=0;
    for(int i=1;i<=n;i++)
        res=max(res,dp[n][i]);
    cout<<res;
    return 0;
}

我们可以发现这里的时间复杂度为 O ( n 3 ) O(n^3) O(n3),能处理的数据范围很小
我们可以对上面的代码进行优化,
其中

if(B[k]<B[j]) t=max(t,dp[i][k]);
此处的B[j]==A[i],所以可以写成
if(B[k]<A[i]) t=max(t,dp[i][k]);
我们要找到最大的B[k],可以提前将max(B[k])求出来

将下面代码优化

    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];
            else {
                int t=0;
                for(int k=1;k<j;k++)
                    if(B[k]<B[j]) t=max(t,dp[i][k]);
                dp[i][j]=t+1;
            }
    }

可以在遍历B[1~j]中求出B[k]<A[i]时的最大的dp[i][k]

    for(int i=1;i<=n;i++){
        int t=0;
        for(int j=1;j<=n;j++){
            if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];
            else dp[i][j]=t+1;
            if(A[i]>B[j]) t=max(t,dp[i][j]);
        }
    }

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3010;
int A[N],B[N];
int dp[N][N];//dp[i][j]表示A[1~i]与B[1~j]且以B[j],结尾的最长公共上升子序列

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&A[i]);
    for(int i=1;i<=n;i++) scanf("%d",&B[i]);
    for(int i=1;i<=n;i++){
        int t=0;
        for(int j=1;j<=n;j++){
            if(A[i]!=B[j]) dp[i][j]=dp[i-1][j];
            else dp[i][j]=t+1;
            if(A[i]>B[j]) t=max(t,dp[i][j]);
        }
    }
    int res=0;
    for(int i=1;i<=n;i++)
        res=max(res,dp[n][i]);
    cout<<res;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189455.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MMCV - browse_dataset.py 可视化config文件数据预处理部分

无论是mmdetection、mmtracking、mmdetection3D等框架&#xff0c;在\tools\analysis_tools中均有一个名为browse_dataset.py的文件。该文件能够帮助用户直接可视化 config 文件中的数据处理部分&#xff0c;查看标注文件是否正确&#xff0c;同时可以选择保存可视化图片到指定…

百度学习经验

如何应对干扰1.将吸引你注意力的东西放在一旁&#xff0c;离开你的视野范围2.告诉大家你有空的时间&#xff0c;和你要专注的时间范围3.跟别人咨询的时候也是一样&#xff0c;不要在他专注的时候大扰别人关于如何做事&#xff0c;控制精力就是按照重要程度排序&#xff0c;不重…

《最佳停止时间》:什么时候可以停止寻找?

分享一个有趣的数学编程知识 《最佳停止时间》&#xff1a;什么时候可以停止寻找&#xff1f; 日常生活有很多"寻找-决策过程"&#xff0c;如果考察所有选项&#xff0c;要花费很长时间&#xff0c;可能还会错失机会&#xff0c;后面遇到的未必有前面的好。能否确定一…

实力见证 | Authing 荣获 2022 中国数字化转型与创新评选之“年度安全创新产品”

近日&#xff0c;由数字产业创新研究中心、锦囊专家、首席数字官联合全国 20 多家 CIO 组织机构、行业协会共同发起的 《2022 中国数字化转型与创新评选》 获奖榜单新鲜出炉&#xff0c;Authing 成功入选该榜单&#xff0c;荣获“年度安全创新产品”。 该榜单自 2022 年 5 月启…

【设计模式】行为型模式·策略模式

学习汇总入口【23种设计模式】学习汇总(数万字讲解体系思维导图) 一.概述 该模式定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以相互替换&#xff0c;且算法的变化不会影响使用算法的客户。 策略模式属于对象行为模式&#xff0c;它通过对算法进行封…

英语学习 作文 1

1 议论文和应用文 1、议论文&#xff1a;essay 1 观点选择&#xff1a;option、choice 2 现象解释&#xff1a;why、what 3 问题解决&#xff1a;how to、solution、measure **4 图片图表&#xff1a;image、cartoon、diagram、chart**2、应用文&#xff1a;信件、通知、报道…

设计模式——创建型模式

目录 4.创建型模式 4.1 单例设计模式 4.1.1 单例模式的结构 4.1.2 单例模式的实现 4.1.3 存在的问题 4.1.4 JDK源码解析-Runtime类 4.2 工厂模式 4.2.1 概述 4.2.2 简单工厂模式 4.2.3 工厂方法模式 4.2.4 抽象工厂模式 4.2.5 模式扩展 4.2.6 JDK源码解析-Collecti…

2023年山东最新建筑施工信号工(建筑特种作业)考试真题题库及答案

百分百题库提供特种工&#xff08;信号工&#xff09;考试试题、特种工&#xff08;信号工&#xff09;考试预测题、特种工&#xff08;信号工&#xff09;考试真题、特种工&#xff08;信号工&#xff09;证考试题库等,提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助…

C++98以及C++11产生随机数的方法

目录引言1、C98标准实现随机数2、C11新标准随机数引擎引言 在C11出现之前&#xff0c;C98使用随机数采用的是C标准库的写法。而在C11出现后&#xff0c;我们生成随机数可以采用更为现代化的方式。 1、C98标准实现随机数 以往生成随机数使用的是cstdlib.h库中的rand()函数&…

基于Node.js的3DTiles三维倾斜摄影模型爬虫

随着小型无人机的普及,乡村级的倾斜摄影模型构建已经越来越简单。一个无人机和一名飞手2个小时内就可以完成。在做WebGIS和Cesium开发时,3DTiles是一种常用的倾斜摄影三维模型的切片格式。3DTiles格式通常有散列和紧凑两种文件组织形式,其中不同工具生成的散列数据使用的索引…

【GNN报告】GNN-LOGS部分报告汇总

Bastain Rieck: Topology-Based Graph Representation Learning 基础 拓扑学习 基于拓扑学习的工作 参考 Bastain Rieck: Topology-Based Graph Representation Learning_哔哩哔哩_bilibili Chaitanya K. Joshi Graph Neural Networks for Geometric Graphs 背景 方法 Geom…

Kenney Assets - 提供数以万计免费商用的游戏制作素材下载,包括 2d、3d素材,游戏音效和游戏 UI

来自荷兰的游戏公司开放了自家游戏的素材包&#xff0c;制作很精美&#xff0c;下载后无需取得授权就能直接商用。 关于 Kenney Assets Kenney Assets 是游戏公司 Kenney 为游戏开发者提供的游戏素材资源网站&#xff0c;主要包括游戏 2D / 3D 人物和场景素材&#xff0c;游戏…

AXI 总线协议学习笔记(1)

引言 此文针对 XILINX的用户指南 UG761进行学习简单对AXI作说明。从下篇文章开始&#xff0c;通过阅读ARM官网的AXI协议标准进行系统学习。可以持续关注~ AXI是什么&#xff1f; AXI是ARM AMBA的一部分&#xff0c;ARM AMBA是1996年首次引入的一系列微控制器总线。 AXI的第…

ORA-29740:evicted by member %d, group incarnation %d

这个错误是在 rac 底下出现的&#xff0c;应该算是个比较严重的错误&#xff0c;就是 某个节点 被 踢&#xff08;evict&#xff09;出去了&#xff0c;导致这个节点重启系统。 这个错误的原因多种多样&#xff0c;而且需要找的日志文件也是很多的&#xff0c;基本上&#xff…

Serverless-云原生服务-概念

云原生服务是包含硬件、架构&#xff0c;硬件&#xff0c;因云而生&#xff0c;所以称为云原生技术。ServerlessFaasBaas同时具有按量付费和弹性伸缩的特点&#xff0c;该架构包括了函数维度和应用维度的两种形态关键字解析BaaS&#xff1a;Backend as a Service&#xff08;后…

termux 部署springboot 及mysql

安装应用后&#xff0c;首先在手机上运行 pkg install openssh 再运行 passwd&#xff0c;改变ssh的密码。这时在pc上用数据线连好手机&#xff0c;打开adb调试&#xff0c;将手机的端口8022映射到PC上&#xff0c;因为termux中ssh默认是8022&#xff0c;再运行一下sshd 运行…

CV-Model【8】:ConvNeXt

文章目录前言1. Abstract & Introduction1.1. Abstract1.2. Introduction2. Modernizing a ConvNet: a Roadmap2.1. Training Techniques2.2. Macro Design2.2.1. Stage ratio2.2.2. "patchif" stem2.3. ResNeXt-ify2.4. Inverted Bottleneck2.5. Large Kernel S…

AWK简单总结

目录AWK简单总结常用命令选项变量内置变量自定义变量printf命令格式AWK简单总结 awk是linux/unix下的一个强大编程工具,他支持用户自定义函数和动态正则表达式&#xff0c;灵活性强&#xff0c;运行速度快。 常用命令选项 -F fs&#xff1a;fs指定输入分隔符&#xff0c;fs可…

利用SMB协议实现局域网内设备文件的共享

文章目录参考资料说明步骤1&#xff1a;[windows]开启SMB协议步骤2&#xff1a;[windows]创建新的用户账号步骤3&#xff1a;[windows]共享文件夹属性-共享-共享属性-共享-高级共享步骤4&#xff1a;[windows]查看共享文件的主机在局域网内的IP地址步骤5&#xff1a;[ipad]打开…

华为机试题:HJ35 蛇形矩阵(python)

文章目录知识点详解1、input()&#xff1a;获取控制台&#xff08;任意形式&#xff09;的输入。输出均为字符串类型。1.1、input()与list(input())的区别、及其相互转换方法2、print() &#xff1a;打印输出。3、算术运算符4、整型int() &#xff1a;将字符串或数字转换为整型…