最长上升子序列(二分)

article/2025/9/20 17:02:28

最长上升子序列

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式
第一行包含整数 N。

第二行包含 N 个整数,表示完整序列。

输出格式
输出一个整数,表示最大长度。

数据范围
1≤N≤100000,
−109≤数列中的数≤109
输入样例

7
3 1 2 1 8 5 6

输出样例:

4
int a[N];//存题目数据的数组 
int q[N];//存每个数对应上升子序列的数组 

题解:q这个数组是一个记录“最小值”的数组,所谓的“最小值”就是——q[i]中每一个点都记录着某一个子序列个数的最小值。
在这里插入图片描述
就比如说这样一组数,q[1]=1,q[2]=2——因为最长子序列长度是1的那一位中‘1’是最小的一个,最长子序列长度是2的那一位中最小的那个数是‘2’。明确了q的概念再来分析性质。
‘4’和‘5’能接到3后面,那么其一定可以接到1后面,因为1比3小,可以为以后的序列留出更大的空间,此时2就可以插入其中,组成{1,2,4,5,6}这样一组最长上升子序列。
代码中的:q[r + 1] = a[i]:
我们可以用二分返回比当前q[i]小的数的下标r(如果当前的ai小于了q[当前]里的数,那么r返回的就是[当前]这个数的下标;此时把当前这个数的q[当前]直接更新成较小的那个数a[i]。如果当前的ai大于了q[当前]里的数,r返回的是当前这个数的下一个点的下标(向上取整);那么你的q[当前+1]这个数就被赋值
如果a[i]小于q[i]我们就更新q[i]让其等于a[i],一直等到第一次出现一个a[i]比前面最小的那个q[i]大,那么我们可以给q[i+1]赋值为a[i],经过一轮迭代,最终q[i+1]也将是比q[i]大且在所有q[i+1]中筛选出来的最小值。
如此更新我们发现q的图像一定是单调的,所以可以用二分更新q数组:
在这里插入图片描述

我们在二分返回r的同时更新长度len,最终len可以更新到的最大值就是我们根据性质推出的最长上升子序列的长度。

#include <iostream>
#include <algorithm>using namespace std;const int N = 100010;int n;
int a[N];//存题目数据的数组 
int q[N];//存每个数对应上升子序列的数组 int main()
{scanf("%d", &n);for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);int len = 0;for (int i = 0; i < n; i ++ ){int l = 0, r = len;while (l < r){int mid = l + r + 1 >> 1;if (q[mid] < a[i]) l = mid;else r = mid - 1;}len = max(len, r + 1);q[r + 1] = a[i];//更新q这个数组}printf("%d\n", len); return 0;
}

7-10 列车调度 (25 分)——天梯赛补题
火车站的列车调度铁轨的 结构如下图所示。在这里插入图片描述
两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?
输入格式:
输入第一行给出一个整数N (2 ≤ N ≤10^5),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。
输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。
输入样例:

9
8 4 2 5 3 9 1 6 7

输出样例:

4

题解:本题难点就是如何抽象成一个最长上升子序列问题。在这里插入图片描述

如果按照左边完全逆序入轨,我们至少需要9条铁轨。如果把4,5交换,那么5就可以和4一起站到一个铁轨上。那么只需要8条轨道。可以发现进入轨道之前的数如果都是递增的,那么就可以按照增序一个个出轨——即一条铁轨。那么这道题就可以看作一个求最长上升子序列的问题||导弹拦截问题||最多铁轨问题。
为什么导弹拦截和最长上升子序列是一致的呢?
同样q这个数组是一个记录“最小值”的数组。
按照上面的二分代码,如果飞来一系列递减的攻击导弹,防御导弹可以拦截比前一次高度低的攻击导弹么因为二分返回用来更新q数组的下标。

 if (q[mid] < a[i]) l = mid;else r = mid - 1;

而一段递减序列的最后一个元素——尾后缀被更新的时候必须打断这一段递减序列,此时我们的二分返回的就是q【下一个下标】(向上取整)——其意义就是最长子序列的个数增加一个||导弹拦截系统增加一套||铁轨条数增加一条。最后我们的q数组存的就是我们的最长上升子序列(上一题),其个数就是最长上升子序列个数,同样也是导弹拦截系统的个数,最少轨道条数。

在这里插入图片描述

代码同第一题。


http://chatgpt.dhexx.cn/article/LqQESJLu.shtml

相关文章

C++最长上升子序列

最长上升子序列简介 题目描述 现有数列a1&#xff0c;a2&#xff0c;a3……aN。在其中找到严格递增序列ai1&#xff0c;ai2&#xff0c;ai3&#xff0c;……aiK&#xff08;1 < i1 < i2 < i3 < …… < iK < N&#xff09;&#xff0c;请找出序列a的最长上升…

LIS最长上升子序列

给定一个数组 &#xff0c;让你找出一个最长上升子序列的长度&#xff0c;例如[1,4,6,2,3,5] 答案为4&#xff1a;[1,2,3,5]。 我们用DP[i]表示以下标为i的元素结尾的子序列的最长上升子序列长度 代码如下&#xff1a; ll p[10010]; ll dp[10010]; int main() {ll n, ans 0…

最长上升子序列优化

引言 上次我们说了基础的最长上升子序列&#xff08;看这一篇前可以先看一下最长上升子序列&#xff09; 这次&#xff0c;我们再说一下如何优化&#xff0c;提高效率 我们先来看一道模板题 题目&#xff1a; 题目描述 输入格式 输出格式 输入样例 3 1 3 2 输出样例 1 …

最长上升子序列(LIS)算法

LIS定义 LIS&#xff08;Longest Increasing Subsequence&#xff09;最长上升子序列 一个数的序列bi&#xff0c;当b1 < b2 < … < bS的时候&#xff0c;我们称这个序列是上升的。 对于给定的一个序列(a1, a2, …, aN)&#xff0c;我们可以得到一些上升的子序列(a…

11.最长上升子序列(LIS)

视频讲解&#xff1a;最长上升子序列_哔哩哔哩_bilibili 解题思路&#xff1a; 1.最长上升子序列的含义是从给定的数中选取尽量多的数字形成单调递增的序列 2.可以把以每一个数字形成单调结尾的方案数看待成一个子问题&#xff0c;然后对后面的子问题提供最优解 3.设定状态…

C++动态规划之最长上升子序列

1 子序列与上升子序列 1.1 子序列 一个序列A{a1,a2,...an}中任意删除若干项&#xff0c;剩余的序列叫做A的一个子序列。例如序列A{1,3,5,4,2}&#xff0c;删除其中的第3项和第5项&#xff0c;得到序列B{1,3,4}&#xff0c;删除其中的第3项和第4项&#xff0c;得到序列C{1&#…

最长上升子序列(c++图文详解)

这题思路是这样&#xff0c;假设这个序列长度为n&#xff0c;存在数组a中&#xff0c;maxlen[i]表示以第i个数为终点的最长上升子序列的长度&#xff0c;它被初始化为1&#xff0c;因为一开始单个字符的最长上升子序列都是1&#xff08;它自己&#xff09;&#xff0c;我们先用…

最长上升子序列(动态规划)

子序列 所谓的子序列就是在原来序列中找出一部分组成的序列。 与子段不同&#xff0c;不需要连续的某一段&#xff0c;但是要保持原序列的先后顺序 最长上升子序列 在子序列的基础上&#xff0c;后一项大于前一项。 【题目描述】 【输入格式】 【输出格式】 【输入样例】 1…

最长上升子序列 (LIS) 详解+例题模板 (全)

欢迎访问https://blog.csdn.net/lxt_Lucia&#xff5e;&#xff5e; 宇宙第一小仙女\(^o^)/&#xff5e;萌量爆表求带飞≡Σ((( つ^o^)つ~ dalao们点个关注呗&#xff5e; --------------------------------我只是一条可爱哒分界线------------------------------- 1.摘要&…

Import Dependency Management with Exclusion

文章来源: Import Dependency Management with Exclusion Exclusion at import won’t work, try excluding it from the actual user of the dependency 意思是&#xff1a; 在dependencyManagement里面的dependency中&#xff0c;使用exclusions&#xff0c;是不会有作用的…

maven配置中的 scope, type,optional, classifier, 传递依赖,exclusions解释

scope用于依赖范围控制,它管理哪些依赖在哪些classpath 中可用&#xff0c;哪些依赖包含在一个应用中. 它的取值列表如下: 关于为什么使用provided 引入 servlet-api,jsp-api的问题的澄清: 在eclispe里创建web项目时&#xff0c;eclipse为我们自动添加了这两个jar包&#xff0…

记录--对于$off,Exclude 和 Extract的一点理解

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 一.typescript 高阶类型 Exclude 和 Extract Exclude<T, U> TypeScript 2.8 中增加了 Exclude 类型&#xff0c;该如何理解这个高级类型的定义呢&#xff1f; type Exclude<T, U> T exte…

[1120]Maven依赖冲突解决之exclusions

1. 背景 1、作为java生态下开发者&#xff0c;往往需要使用大量线程的第三方库&#xff0c;一般都是以jar包形式存在。 2、maven作为事实上主流的jar包依赖管理工具&#xff0c;Idea和Eclipse都支持创建maven工程来管理jar包依赖。 3、使用maven进行jar包依赖管理时&#xff0…

logical exclusive 与 physical exclusive 的区别

数字电路中一般会有多个clock&#xff0c;这些clock 相互之间有些是同步的&#xff0c;需要做 timing check 的&#xff0c;有些是异步的&#xff0c;不需要做 timing check 的&#xff0c;还有些是互斥的&#xff0c;需要 exclude 掉的&#xff0c;这些关系就需要在 sdc 中声明…

Maven中 排除依赖 exclusions

使用maven进行jar包依赖管理时&#xff0c;maven会自行管理jar包及其依赖链条&#xff0c;但往往会遇到依赖冲突问题&#xff0c;这时候就可以尝试使用exclusions来进行依赖管理 demo:排除tomcat 启用 jetty <dependency><groupId>org.springframework.boot</g…

Exclusive or

题目连接 题意&#xff1a; 每次给一个n&#xff0c;求 (2≤n<10500) 分析&#xff1a; 先说一下自己的想法&#xff0c;如果将n换成二进制数&#xff0c;也就一两千位左右&#xff0c;那么一位一位处理是可以接受的。将0-n写成二进制形式后&#xff0c;显然所有数某一个二进…

Maven依赖冲突解决之exclusions

Maven依赖冲突解决之exclusions 1. 背景 作为java生态下开发者,往往需要使用大量线程的第三方库,一般都是以jar包形式存在。maven作为事实上主流的jar包依赖管理工具,Idea和Eclipse都支持创建maven工程来管理jar包依赖。使用maven进行jar包依赖管理时,maven会自行管理jar包…

【带你吃透C++】引用详解(引用和指针的区别)

引用 1 引用概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。 比如&#xff1a;李逵&#xff0c;在家称为"铁牛"&#xff0c;江湖上人称"…

浅析C++中引用与指针的区别

引用和指针的概念及区别 1. 引用及指针概念1.1 指针概念1.2 引用概念 2. 引用与指针的区别 1. 引用及指针概念 如果熟悉指针和引用的使用&#xff0c;应该能感觉到指针和引用在很多场景使用起来还是有很大的相似性的&#xff0c;尽管它们在语法层面上是俩个完全不同的概念。 那…

C语言-引用和指针的区别?

①引用的格式&#xff1a;数据类型 &引用名 变量名&#xff1b; 指针的格式&#xff1a;数据类型 *变量名指向的变量地址&#xff1b;②使用引用一定要进行初始化 指针为了不出现野指针&#xff0c;也要进行初始化为NULL ③引用只能对数组的元素使用&#xff0c;不能对整个…