最长上升子序列解法及其优化

最长上升子序列(LIS)的5种解法对比:从暴力搜索到树状数组优化 本文详细对比了最长上升子序列(LIS)的5种解法,包括暴力搜索、动态规划、贪心+二分优化、树状数组和线段树优化。从O(2ⁿ)到O(nlogn)的时间复杂度分析,帮助读者根据问题规模选择最优算法,特别适合算法竞赛和面试准备。重点介绍了动态规划和贪心+二分这两种高效解法。 阅读详情

例题

给定一个长度为 N 的数列 a[i],求数值严格单调递增的子序列的长度最长是多少。
数据范围
1≤N≤1000

朴素解法

这道题很经典吧awa,就是一道普通的dp,用一个一维的数组 dp[i] 代表以第 i 个数字结尾的最长上升子序列,然后再求出dp数组里面的最大值就是答案;代码如下;

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    vector<int> a(n + 1), dp(n + 1, 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int res = 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j < i; j++)
        {
            if (a[j] < a[i])
                dp[i] = max(dp[i], dp[j] + 1);
            res = max(res, dp[i]);
        }
    cout << res;
    return 0;
}

优化(非常妙awa)

我们来看一组数据:

7
3 1 2 1 8 5 6

分析一下:对于数组中的 8 ,如果其可以接到 3 后面,那么其必定能接到 1 后面,并且以 3 结尾的最长上升子序列和以 1 结尾的最长上升子序列长度相同,都是1,这个时候我们成 1 比 3 更好;

有了以上的分析,我们可以这样处理:用一个数组 q 来存储最长上升子序列长度为 i 的最好的数字,我们就可以得到一张图:
q数组的图
那为什么这张图是单调上升(即q[i, j] > q[i - 1, j])的呢,别急,这里给出证明:若q[i] <= q[i - 1],则q[i, j - 1] < q[i - 1][j]( q[i, j - 1]代表的是排除掉最上面那个数,得到了一个长度为k - 1的上升子序列,里面所存的结尾 ),可以得到q[i, j - 1] < q[i - 1, j],而 q数组 存的是 最好的 那个数(即最长上升子序列长度为k,最小的结尾),故q[i - 1, j]不是最小的那一个,矛盾了;

那么有了这个单调性,可以想到什么呢?二分!对于一个新的数a[i],我们二分找到一个小于a[i]的最大的 结尾值 ,并且把a[i]接上去,假设最大的接位置对应的最长上升子序列长度为 k 那么 k + 1 的最好的值就变成a[i]了( 因为q[k] < q[i] < q[k + 1] );

请看代码:

signed main()
{
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    vector<int> a(n + 1), q(n + 1, -1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int len = 0;
    for (int i = 1; i <= n; i++)
    {
        int l = 0, r = len, mid;
        while (l < r)
        {
            mid = l + r + 1 >> 1;
            if (q[mid] < a[i])
                l = mid;
            else
                r = mid - 1;
        }
        q[l + 1] = a[i];
        len = max(len, l + 1);
    }
    cout << len << endl;
    return 0;
}

其实到这里都不太像dp了o.o;

巨硬面试题:最长上升子序列(动态规划+二分优化思路) 给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。 →在线做题地址 说明 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。 维基百科→https://en.wikipedia.org/wiki/Longest_increasing_subsequence 样例 1: 输入: [5,4,1,2,3] 输出: 3 解释: LIS 是 [1,2,3] 样例 2: 输入: [4,2,4,5, 阅读详情

相关推荐

dp(9) 动 态 规 划 进 阶 1893: 【提高】最长上升子序列 LIS(2)

本文介绍了最长上升子序列(LIS)问题的两种解法。第一种是动态规划解法,时间复杂度O(n²),通过维护以每个元素结尾的LIS长度来求解,但当n较大时会超时。第二种优化解法采用贪心+二分,时间复杂度O(nlogn),通过维护不同长度LIS的最小末尾值,利用二分查找进行更新。文章以东方博宜OJ的1893题为例,给出了两种解法的详细思路和C++代码实现,重点分析了第二种高效解法的核心思想:用更小的末尾值替换原有值以获得更长LIS的可能性。该解法适用于大规模数据(n≤100000)。

m0_72568314的博客 24

最长上升子序列和

最长上升子序列长度 题意:给定一个无序的整数数组,找到其中最长上升子序列的长度。 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。 解法:这是一道经典的动态规划 状态表示:dp[i]表示序列前i个数(必须包含nums[i])的最长上升子序列长度 状态转移:dp[i] = max(dp[j] + 1), 0&lt...

qq_40438165的博客 1963

report_delay_calculation/check_timing/report_annotated_parasitics/report_analysis_coverge

如何debug 一颗cell 或一段net 的delay, 常用的办法是用report_delay_calculation 报这颗cell 或这段net, 会得到形式如下的report, 从该report 中可以得到: 表头需要特别关注的是command, 确定report 的对象及加的option; From/To pin: cell 的input pin 和...

diedai7174的博客 1798

SCAU OJ 19523 最长上升子序列长度

时间限制:1000MS 代码长度限制:10KB。

2401_87578361的博客 293

对族实例进行任意的矩阵变换,需要什么样的族?

问:一个小问题,想向您请教一下。 能不能实现一个这样的操作:创建了一个常规模型的FamilyInstance,然后知道旋转和平移的矩阵,能否根据变换矩阵更新FamilyInstance的位置,绕任意轴旋转任意角度。 请问什么样的实体才能在revit项目文件中任意旋转?貌似一般的实例只能在XY平面内旋转,并且LocationPoint中只有一个Rotation参数。答:您好,因为Revit里面的构件

我爱Revit —— BIM应用及BIM应用软件解决方案专栏 3628

5分钟搞懂知识抽取:如何把非结构化数据变成知识图谱的宝藏?

本文通过一个电商评论分析实战案例,详细解析了如何利用spaCy、Neo4j等工具,将非结构化文本数据转化为结构化知识图谱的完整流程。文章重点阐述了知识抽取的核心步骤,包括命名实体识别、关系抽取以及知识存储与查询,帮助读者快速掌握将数据转化为知识宝藏的关键技术。

weixin_29054245的博客 235

最长上升子序列 LIS【DP的O(n^2)及贪心+二分的O(nlogn)解法】

最长上升子序列 给你一个长度为N的序列,求其最长上升子序列的长度。 样例输入: 6 1 6 2 4 3 5 样例输出: 4 解释:其最长上升子序列的长度为4。可以是{1 2 4 5 }或者{1 2 3 5} 注意:子序列是不连续的。 假设我们把序列储存在a数组中,并且从下标1开始存储。 动态规划解法 定义 f[i] 表示到a[i] 为止的最长上升子序列的长度。(其中a[i]必须被选中,必须以a[i]结尾) 所以动态转移方程是 f [ ...

马小超 260

储能逆变器动态无功补偿:从原理到算法实现

本文深入解析了储能逆变器动态无功补偿的核心原理与算法实现。通过四象限运行与解耦控制技术,储能逆变器可在充放电的同时,快速、精准地调节无功功率,有效提升电网电能质量与功率因数。文章详细阐述了从相位调节、容量限制到PI控制算法的完整技术路径,并结合工程实践,探讨了其在光伏/储能系统中的协同控制策略与进阶应用价值。

weixin_29216353的博客 207

LIS(最长上升子序列)的 n ^ 2, nlogn解法以及路径标记

最长上升子序列(Longest Increasing Subsequence,LIS)是一个数列中最长的(非)严格上升的子序列, LIS的求解是DP思想的一个经典体现, 这里通过例题来介绍两种复杂度不同的解法和一个标记路径的问题。 一. n ^ 2 解法(双层循环递推关系式) 例:hdu 1160 链接戳我 题意是一只老鼠有体重跟速度两种属性, 每一行会都会输入一只老鼠的体重和速度,同时每...

Kruskal的博客 2922

Linux V3H 平台开发系列讲解(摄像头)2.3.1 MAX96912 MAX96717 GMSL1 CSI 2lane配置

​ 单路摄像头,数据流类型YUV422, mipi接口,经过MAX96717 串行器,gmsl1链路 到解串器MAX96712,最后mipi csi 2lane(lane0 lane1)输出到 renesa v3h soc开发板; ​

xian18809311584的博客 579

炼金术士的试炼:2026年企业信用信息公示系统极验五维反爬下的Python数据博弈与破局之道

企业信用信息公示系统(以下简称“公示系统”)作为国家市场监督管理总局权威发布平台,承载着全国亿万市场主体的登记、许可、处罚等核心信用数据。对于金融风控、市场分析、商业尽职调查等领域,这些数据具有不可替代的黄金价值。然而,公示系统在2025年至2026年间进行了数次史诗级的安全加固,构建了包含动态令牌、极致混淆的JavaScript混淆、无感行为指纹、智能语义验证码以及WebAssembly防护在内的“五维反爬长城”。

2201_76125261的博客 350

最长上升子序列

最长上升子序列 在leetcode看到一个解法,说一下自己的理解 动态规划设计方法&&纸牌游戏讲解二分解法 解答中对于后一种解法没有证明,我试图对之做一些直觉上的说明. 想法是,我们可以将原序列分为几类,第iii类记为SiS_iSi​,定义为:aaa在某些上升子序列中,且aaa在这些上升子序列中的出现位置最大为iii,则aaa属于SiS_iSi​.例如: 333可能出现在序列{33...

qq_31724343的博客 172

115网页版VR模式终于能用了!电脑直接播放vr视频沉浸感满满 115vr播放 无需vr头盔播放vr视频 在线vr播放器 115网盘360度视频播放方法 115全景视频播放教程

油猴 + 脚本让你网页端直接开启 VR 模式支持 360 视频拖动视角,非常沉浸适合电脑设备直接用无需vr头盔也能轻松畅看vr视频,希望也能帮到你。如果你也被 115 的限制搞烦了,不妨试试这招。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 5711

51Nod 1134 最长上升子序列 【动态规划】

51Nod 1134 最长上升子序列 【动态规划】 给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。 收起 输入 第1行:1个数N,N为序列的长度(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列的元素(-10^9...

qq_28640193的博客 270

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

最长上升子序列(LIS) nlogn解法

二分+dp

阿正的梦工坊 4993

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

“序列优化探究:最长上升子序列的算法发现与应用“

最长上升子序列是指在一个给定序列中,找到一个最长的子序列,使得子序列中的元素单调递增。例如,序列 [1, 3, 5, 4, 7] 的最长上升子序列是 [1, 3, 5, 7],长度为4。这是一个经典的动态规划问题。假设dp[i]表示以第i个元素为结尾的最长上升子序列的长度。可以用一个嵌套循环来遍历所有的元素对,如果前一个元素小于后一个元素,则可以将后一个元素添加到前一个元素所在的最长上升子序列中,从而得到以第i个元素为结尾的最长上升子序列长度。

Rockivy的博客 2003

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

最长上升子序列(LIS)

最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。

congyuyoudao的博客 1362

最长上升子序列的学习

(大部分内容都是知乎大神pecco的内容 在此写下博文为了自己更好的消化)转移函数:dp[i]表示以nums[i]为最后一个元素的上升子序列的长度dpimaxdpj10≤jiandnumsinumsj。

qq_27127603的博客 973

最长上升子序列(LIS)问题的解决及优化

介绍了LIS问题的动态规划思想,并通过二分查找将其时间复杂度优化到对数级。

yuhaomogui的博客 2590

洛谷java实现(P1439[模板]最长公共子序列)

题目链接:https://www.luogu.com.cn/problem/P1439 首先这是一道绿题,如果用动态规划(时间复杂度n^2)对于n=10 ^5肯定过不了,当然动态规划适合leetcode这道题1143. 最长公共子序列感兴趣可以看看 题解如下: /** * 动态规划+内存优化 */ public int longestCommonSubsequence(String text1, String text2) { if (text1 == null || te.

malloc_can的博客 344

最长上升子序列问题

最长上升子序列问题

qq_51704853的博客 255

最长上升子序列的最优算法

最长上升子序列的最优算法 1 问题背景 最长上升子序列问题(Longest Increasing Subsequence)在算法教学中的经典问题,在学习动态规划(Dynamic Programming)相关内容时经常出现。在动态规划这一章节中出现的频率只比最长公共子序列(Longest Common Sequence)小。最长上升子序列问题的动态规划解法的时间复杂度为n2,而我们...

antangzhang9759的博客 748

最长上升子序列(LIS)及其优化O(nlongn)

按照数据结构来划分的话,最长上升子序列(LIS)是属于线性DP,其作为动态规划经典入门模型,重要性也是不言而喻的。而LIS问题也有很多种变型,对于这些问题有的超过了动态规划的适用范围,有的需要对转移方程进行更改,需要具体问题具体分析。 前置知识: - 子序列的概念 - 动态规划一般步骤 - 二分查找 问题模型:给定一个长度为N的数列A,求数值单调递增的子序列长度最长是多...

帅比王的博客 8737

最长上升子序列(线性dp/LIS)专题总结

本来大一就学了的线性dp, 正好这几天遇到了这样的问题也忘得差不多了, 而且学弟们也都在学这个内容, 我花了一天多的时间刷LIS的题, 写一写我刷这种题的感想。

Tanya_xiaomai的博客 562
上一篇: 二分答案耶~
下一篇: 模运算的一些性质
ResCells
博客等级 码龄4年 191粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值