《最长单调子序列》基础概念

算法入门竞赛经典 动态规划 动态规划入门 动态规划的第二个解法 阅读详情

一、算法概述

  1. 问题定义:给定一个整数序列,找到其中最长的严格递增(递减)子序列的长度。子序列中的元素不需要连续,但必须保持原序列的顺序。例如,序列 [10, 9, 2, 5, 3, 7, 101, 18] 的最长递增子序列是 [2, 3, 7, 101],长度为 4。

  2. 应用场景:该算法在生物信息学(DNA序列分析)、数据压缩和计算机视觉等领域有广泛应用。

二、算法思路

  1. 动态规划思想:维护一个辅助数组 g,其中 g[i] 表示长度为 i 的递增子序列的最小可能末尾元素。通过贪心策略和二分查找优化,高效地更新该数组。

  2. 核心策略:对于每个元素,尝试将其插入或替换到辅助数组 g 中的适当位置,以保持数组的单调性。插入位置由二分查找确定。

  3. 关键性质:

    • 数组 g 始终保持严格递增。
    • 数组 g 的长度即为当前找到的最长递增子序列的长度。

三、伪代码实现

算法:最长递增子序列(贪心+二分优化)
输入:数组 a[0..n-1],数组长度 n
输出:最长递增子序列的长度

function getLIS(n, a[]):
    // g[i] 表示长度为 i+1 的递增子序列的最小末尾元素
    g[0..n-1]
    gSize = 0  // 当前最长递增子序列的长度
    
    for i = 0 to n-1:
        // 二分查找插入位置
        l = -1, r = gSize
        while l + 1 < r:
            mid = (l + r) / 2  // 向下取整
            if g[mid] >= a[i]:
                r = mid
            else:
                l = mid
        
        // 插入或替换操作
        if r == gSize:
            g[gSize] = a[i]
            gSize = gSize + 1
        else:
            g[r] = a[i]
    
    return gSize

// 主程序
输入 n
输入数组 a[0..n-1]
输出 getLIS(n, a)

四、算法解释

  1. 初始化阶段:

    • 创建辅助数组 g 用于存储递增子序列的最小末尾元素。
    • gSize 记录当前最长递增子序列的长度,初始为 0。
  2. 遍历处理每个元素:

    • 二分查找:对于每个元素 a[i],在 g 中找到第一个大于或等于 a[i] 的位置 r。
    • 插入或替换:
      • 如果 r 等于当前 gSize,说明 a[i] 可以扩展当前最长子序列,将其添加到 g 的末尾。
      • 否则,将 g[r] 替换为 a[i],以减小长度为 r+1 的子序列的末尾元素,为后续扩展提供可能。
  3. 示例演示:

    • 输入数组 [3, 1, 2, 5, 4, 6]。
    • 处理过程:
      • 处理 3:g = [3],长度 1。
      • 处理 1:g = [1],替换 3。
      • 处理 2:g = [1, 2],扩展长度。
      • 处理 5:g = [1, 2, 5]。
      • 处理 4:g = [1, 2, 4],替换 5。
      • 处理 6:g = [1, 2, 4, 6],最终长度为 4。
  4. 正确性证明:

    • 数组 g 始终保持严格递增,确保二分查找的正确性。
    • 通过替换操作,贪心策略保证了每个长度的子序列末尾元素尽可能小,从而允许后续元素更容易扩展。

五、复杂度分析

  1. 时间复杂度: O ( n l o g n ) O(n log n) O(nlogn),其中 n n n 是数组长度。每个元素的处理需要 O ( l o g n ) O(log n) O(logn) 的二分查找。
  2. 空间复杂度: O ( n ) O(n) O(n),主要用于存储辅助数组 g。
  3. 与朴素 DP 的对比:传统动态规划方法的时间复杂度为 O ( n 2 ) O(n²) O(n2),而本算法通过贪心和二分优化将复杂度降低到 O ( n l o g n ) O(n log n) O(nlogn),适用于大规模数据。

  本文为作者(英雄哪里出来)在抖音的独家课程《英雄C++入门到精通》、《英雄C语言入门到精通》、《英雄Python入门到精通》三个课程的配套文字讲解,如需了解算法视频课程,请移步 作者本人 的抖音直播间。

夜深人静写算法(二十)- 最长单调子序列 一类简单动态规划问题 阅读详情

相关推荐

content-pipeline:一条可落地的内容生产流水线

content-pipeline 是一种将内容创作工程化的系统性方法,其核心在于用确定性流程替代碎片化人工操作。它基于结构化提示(prompt)、预置叙事框架与品牌参数固化三大原理,实现从素材输入到多平台发布的端到端自动化。技术价值体现在显著降低认知负荷、保障输出一致性、支持本地化资源绑定与闭环反馈校验。典型应用场景包括技术教程批量生成、跨平台(公众号/小红书/即刻)内容适配、AI写作质量可控迭代等。本文深入解析其作为‘内容制造业’基础设施的底层设计逻辑与实操路径,尤其聚焦Claude Code环境下的真实

weixin_31199559的博客 265

【动态规划】最长单调子序列

详细讲解如何设计一个O(n2)的算法实现查询最长单调子序列

Coco416的博客 1731

Windows10下部署Heygem进行数字人生成

对于使用Heygem生成数字人,需要注意几个问题: + 需要使用Nvidia的显卡。 + 需要在Windows上进行本地部署。主要原因为客户端是Windows的,客户端对上传的视频写入硬编码的`D:\heygem_data\voice\data`目录,需要在容器上读取这些文件。 + 需要在Windows上部署Docker,将Windows的目录映射到容器中,由容器中的服务进行读取。 + 需要特别注意,一定要有D盘,这个D盘是Windows的D盘,不能是插入的USB设备后产生的D盘。 + 需要下载3个Doc

冀辉的博客 5617

经典DP-最长单调子序列

最长递增子序列的个数 知识点 Arrays.fill(count, 1); 是 Java 中的一个方法调用,用于将数组 的所有元素设置为指定的值,即 。这个方法来自于 类,是一个静态工具类,提供了很多用于操作数组(例如排序、搜索、填充等)的静态方法。在这个特定的情境下, 被用来初始化 数组。由于我们正在计算最长递增子序列的个数,每个元素至少可以作为一个长度为 1 的递增子序列的结束元素。因此, 数组的每一个位置都被设置为 ,意味着每个元素开始时都被视为一个独立的递增子序列。

qq_73886051的博客 568

海康视觉平台VisionMaster使用学习笔记(1)

双击图像源设置图像源的属性,像素格式分为Mono8和RDB24分别对应导入的图像是彩色还是黑白。打开相机驱动软件MVS,对连接的相机进行属性上的配置,先对相机的IP进行对应的设置。将自动触发的使能打开,保存配置好的相机属性,默认保存到用户集1中。点击MVS软件中的触发按钮,查看相机是否进行正常的触发拍照。打开VM软件添加一个图像源,选择图像源选项拖出图像源。回到VM软件中将选择相机选项选择到配置好参数的相机。取图方式也可以调整为相机取图,将图像源改为相机。双击相机进行连接后对相机的属性进行配置。

A567852的博客 1万+

【MCU】一种基于RTOS的无应答重发机制

文章目录一、背景描述二、结构框图三、基于RTOS的信号量的实现(3-1)思路描述(3-2)步骤(3-2-1)定义超时重发信号量(3-2-2)定义发送线程入口(3-2-3)定义接收线程入口四、基于定时器的实现(4-1)思路描述(4-2)步骤(4-2-1)创建定时器(4-2-2)定义定时器超时处理函数(4-2-3)定义发送线程入口(4-2-4)定义接收线程入口 一、背景描述 ​ 在微控制器之间进行数据通信时,大多需要添加无应答重发机制,以增强数据交互和通信的稳定性。 在使用UART通信的双方设备,当一次数据传输

iriczhao的博客 1522

最长单调子序列(动态规划)

最长上升子序列(Longest Increasing Subsequence),简称LIS,也有些情况求的是最长非降序子序列,二者区别就是序列中是否可以有相等的数。 例如: 对于序列(1, 7, 3, 5, 9, 4, 8),我们就会得到一些上升的子序列,如(1, 7, 9), (3, 4, 8), (1, 3, 5, 8)等等,而这些子序列中最长的(如子序列(1, 3, 5, 8) ),它的长...

weixin_44350170的博客 601

2025年GESP12月认证C++一级真题解析

摘要 本文包含13道C++编程选择题,每题2分,涉及语法、运算符、循环、条件判断等知识点。题目考察了变量命名规则、运算符优先级、赋值语句、循环控制、格式化输出等内容。部分题目解析与标答存在差异,例如第4题逗号表达式输出应为5但标答为4,第6题赋值运算结果应为4 4但标答为3 4等。这些题目适合用于检验基础编程能力,但需注意部分标答可能存在争议,建议结合具体编译环境验证。最后一题考察"漂亮数"判断,要求填写数字某位能被3整除的条件表达式。

lan_in的博客 741

最长递增子序列

问题 给定一个长度为N的数组,找出一个最长的单调自增子序列(不一定连续,但是顺序不能乱)。例如:给定一个长度为6的数组A{5, 6, 7, 1, 2, 8},则其最长的单调递增子序列为{5,6,7,8},长度为4. 解法1:最长公共子序列法 这个问题可以转换为最长公共子序列问题。如例子中的数组A{5,6, 7, 1, 2, 8},则我们排序该数组得到数组A‘{1, 2, 5, 6, 7,...

切梦 5416

【2024-06-21】网易互娱秋招实习笔试三道编程题解

恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经。作者@TechGuide【全网同名】

试问道几许 1055

YOLO26-seg分割优化:FPN涨点&轻量化篇 |多级特征融合金字塔(HS-FPN),助力小目标检测

​​​​​摘要:本研究对Ultralytics YOLO26进行了全面分析,重点阐述了其关键架构改进及其在实时边缘目标检测中的性能基准测试。YOLO26于2025年9月发布,是YOLO系列最新、最先进的成员,专为在边缘及低功耗设备上实现高效、精确且易于部署的目标而构建。本文依次详述了YOLO26的架构创新,包括:移除了分布焦点损失(DFL);采用端到端的无NMS推理;集成了渐进损失(ProgLoss)与小目标感知标签分配(STAL);以及引入了用于稳定收敛的MuSGD优化器。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 279

Dilworth定理:最少的下降序列个数就等于整个序列最长上升子序列的长度

注意,显然DP是递增的(两种转移都不会破坏递增性),但这并不意味着它就是所求的上升子序列,你看,下一个元素是2,它会把。好了,最后得到的数组长度是4,所以最长上升子序列的长度就是4。4->8是长度为2的上升子序列,4->5也是,但是5比8更小,所以。把n个人提出来成为原序列的一个子序列,根据题意这个子序列中的元素是单调递增的(即后一项总是大于前一项),我们称为。更新成{2, 5, 6, 7},但原序列并没有一个子序列是{2, 5, 6, 7}。现在有序列4,8,9,5,6,7,2,7求LIS。

island1314的博客 3271

2023年12月机器人技术等级考试试卷(三级理论) 试题解析

2023年12月机器人技术等级考试试卷(三级理论) 试题解析

http://www.cierobot.com 4095

子序列问题

最长公共子序列 例:求两个字符串最长公共子序列长度。如a[] = {"abcedf"}, b[] = {"abtrenf},则最长公共子序列为abef,长度为4 伪代码: 1 for(i...a[]的长度) 2 for(j...b[]的长度) 3 { 4 dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);...

weixin_30415801的博客 113

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

杭电5256序列变换

序列变换 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 5256 Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改

z2664836046的博客 337

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

最长递增子串(LIS)

给定一个序列,要求求出该序列的最长单调子序列, 即 longest increasing subsequence,这是一个经典的动态规划求解问题。 设给定序列为 a[],大小为 n,如何求其最长单调子序列呢?考虑将最长单调子序列的长度作为所求的最优值,最长单调子序列必定以序列a[]中的某一个元素结尾。 设序列count[i]为以a[i]结尾的最长单调子序列的长度,那么a[]的LIS的长度...

weixin_33767813的博客 186

zzulioj2518: 最大下降矩阵【DP】

题目描述 我们称一个矩阵是下降矩阵,当且仅当,矩阵的每一列都是严格下降的。很显然,这个要求很苛刻,大多数矩阵都无法满足。但是显然如果消去一些行,一定可以使得这个矩阵变成下降矩阵。 现在给出一个n行m列的矩阵,请你求出最少消去多少行,可以使得这个矩阵变为下降矩阵。 输入 输入第一行包含两个正整数n,m分别表示矩阵的行数和列数。(1<=n,m<=300) 接下来n行,每行有m个数,中...

独钓门前月 534

期末算法edu

设计算法求解整数的划分问题 #include<stdio.h> const int N=1000; int n; int cnt=0; int dfs(int n,int m){ if(n==1||m==1){ return 1; } if(n>m){ return dfs(n-m,m)+dfs(n,m-1);//不包含包含 } if(n>m){ return dfs(n,n); } return dfs(n,n-1)+1; } int main(){

Z_blog 544

算法第三章作业

1、对动态规划的理解 能用动态规划解决的问题有两大特性:最优子结构特性、重叠子问题特性 最优子结构即:要求原问题的最优解,必先求子问题的最优解 重叠子问题即:在求各个子问题的最优解时会出现重复计算的情况 用动态规划解题的步骤: 1)分析最优子结构 2)建立递归关系,列出递归方程 3)计算最优值 4)构造最优解 这四个步骤列出来好像很简单,但是我觉得实际应用起来还是有难度的,特别是...

weixin_30871293的博客 1627

信息学竞赛中的数学 习题集1031-1040(10题)

信息学竞赛中的数学 习题集1031-1040(10题)

青少年趣味编程 1145

最长单调子序列求解

本文给出了如下题目的参考解答,虽然方法并不是最优,但详细的分析具有很好的参考价值!题目:已知一个序列,由随机数构成,求其最长单调子序列。要求: 单调分严格和不严格两种情况,并分别求解并输出一个最长单调子序列和所有符合要求的子序列。

jin的专栏 3095

最长单调子序列

最近在opj上刷动态规划,遇到的比较多的就是最长单调子序列问题,有几道题调着确实挺费劲,写一下。 描述 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3

Skywalker_____的博客 728

最长单调子序列问题(LIS,dp入门)

dp的一种很简单的题型。 小编便以两道题来介绍一下。

蒲公英殇的博客 794

专题:最长单调子序列(LIS)问题

专题:最长单调子序列(LIS)问题 (4.27 记录) LIS问题是DP当中的一个很经典的问题。 LIS问题的核心在于状态的保护和转移。 一.LIS的长度 解法1:一般DP 时间复杂度O(n2) 很显然,对于某一个点i,1-i的最长单调子序列是唯一的,而以i结尾的最长单调子序列也是唯一的。这样就有两种思路: A dp[i]表示1-i中出现的最长单调子序列的长度; B dp[i]表示以i结尾的最长单调子序列的长度。 这两种思路唯一的区别在于dp是否要转移,或者更直观的来说,区别在于dp[n]是否就是最长单调子

eliyou的博客 1238

最长公共子序列LCS和 最长单调子序列 及其二分优化

最长公共子序列LCS和最长上升子序列LIS都是动态规划的经典例题,再度回顾这两个例题,已经有了更深一些的理解和优化方式。这里系统整理一下 。 一.最长单调子序列 1.最长上升子序列 最朴素的dp思路,就是对一个序列a[i],设一个dp数组, 其中dp[i]的含义为以a[i]结尾的最长上升子序列的长度。 那么我们考虑当前的a[i]与与a[i]之前的元素的关系, 如果当前的a[i]与a[i]之前的a[j]满足递增关系,那么dp[i]的状态可以由dp[j]得到,对每个先前状态取最值即为当前状态的最.

m0_60777643的博客 2618
上一篇: 《最大子段和》基础概念
下一篇: 《最长公共子序列》基础概念
英雄哪里出来
英雄哪里出来 2021年博客之星Top1 2021年博客之星Top1 领域专家: 系统编程技术领域 领域专家: 系统编程技术领域
博客等级 码龄17年 30万+粉丝 1016原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值