首页 > 其他分享 >最长上升子序列——二分法

最长上升子序列——二分法

时间:2024-04-07 11:58:21浏览次数:24  
标签:ll 数是 二分法 ge low 序列 INF 最长

前置

设 l o w i low_i lowi​ :长度为 i i i 的上升子序列末尾数的最小值

我们要使 l o w i low_i lowi​ 尽量小,这样后面的元素就更有可能加入到当前的上升子序列中。

举例:

序列 A :1 2 3
序列 B :1 2 5

这时如果后面有一个元素是 4 4 4,它只能加入到 序列 A 序列A 序列A中,不能加入到 序列 B 序列B 序列B中。

维护

对于原序列 a a a中的每一个元素,二分找到第一个大于等于 a i a_i ai​的 l o w i low_i lowi​,用 a i a_i ai​更新 l o w i low_i lowi​。

举例:

我们用#来代表极大值( I N F INF INF)

下面我的表示方法是 数组名+下标(值),如 a 3 ( 7 ) a_3(7) a3​(7)表示数组 a a a的第3个数,它的值是7。

原序列 a a a:1 2 4 1 3 4

数组 l o w low low:# # # # # #

a 1 = 1 a_1=1 a1​=1:
第一个 ≥ a 1 ( 1 ) \ge a_1(1) ≥a1​(1)的数是 l o w 1 ( I N F ) low_1(INF) low1​(INF),用 a 1 ( 1 ) a_1(1) a1​(1)更新 l o w 1 low_1 low1​。
数组 l o w low low:1 # # # # #

a 2 = 2 a_2=2 a2​=2:
第一个 ≥ a 2 ( 2 ) \ge a_2(2) ≥a2​(2)的数是 l o w 2 ( I N F ) low_2(INF) low2​(INF),用 a 2 ( 2 ) a_2(2) a2​(2)更新 l o w 2 low_2 low2​。
数组 l o w low low:1 2 # # # #

a 3 = 4 a_3=4 a3​=4:
第一个 ≥ a 3 ( 4 ) \ge a_3(4) ≥a3​(4)的数是 l o w 3 ( I N F ) low_3(INF) low3​(INF),用 a 3 ( 4 ) a_3(4) a3​(4)更新 l o w 3 low_3 low3​。
数组 l o w low low:1 2 4 # # #

a 4 = 1 a_4=1 a4​=1:
第一个 ≥ a 4 ( 1 ) \ge a_4(1) ≥a4​(1)的数是 l o w 1 ( 1 ) low_1(1) low1​(1),用 a 4 ( 1 ) a_4(1) a4​(1)更新 l o w 1 low_1 low1​。
数组 l o w low low:1 2 4 # # #

a 5 = 3 a_5=3 a5​=3:
第一个 ≥ a 5 ( 3 ) \ge a_5(3) ≥a5​(3)的数是 l o w 3 ( 4 ) low_3(4) low3​(4),用 a 5 ( 3 ) a_5(3) a5​(3)更新 l o w 3 low_3 low3​。
数组 l o w low low:1 2 3 # # #

a 6 = 4 a_6=4 a6​=4:
第一个 ≥ a 4 ( 4 ) \ge a_4(4) ≥a4​(4)的数是 l o w 4 ( I N F ) low_4(INF) low4​(INF),用 a 6 ( 4 ) a_6(4) a6​(4)更新 l o w 4 low_4 low4​。
数组 l o w low low:1 2 3 4 # #

最长上升子序列的长度就是最大的值不为INF的下标,在此样例中就是4.

代码

以洛谷的这道题为例。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a[1000005],low[1000005],len=0;
signed main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(ll i=1;i<=n;i++)cin>>a[i];
	memset(low,0x3f,sizeof(low));
	for(ll i=1;i<=n;i++){
		ll L=1,R=len+1,res=0;
		while(L<=R){
			ll mid=(L+R)>>1;
			if(low[mid]>=a[i]){R=mid-1;res=mid;}
			else L=mid+1;
		}
		low[res]=a[i];
		if(res==len+1)len++;
	}
	cout<<len<<endl;
	return 0;
}

如果你还有问题,请在评论区留言或私信,我会尽量在24小时内解答。

比起点赞和关注,我更希望你们可以说出你们不懂的地方是哪。

标签:ll,数是,二分法,ge,low,序列,INF,最长
From: https://blog.csdn.net/MC_wansui/article/details/137435683

相关文章

  • 18天【代码随想录算法训练营34期】● 513.找树左下角的值 ● 112. 路径总和 113.路径
    513.找树左下角的值#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:deffindBottomLeftValue(self......
  • Tuxera2023 NTFS for Mac下载,安装和序列号激活
    对于必须在Windows电脑和Mac电脑之间来回切换的Mac朋友来说,跨平台不兼容一直是一个巨大的障碍,尤其是当我们需要使用NTFS格式的硬盘在Windows和macOS之间共享文件时。因为Mac默认不支持写入NTFS磁盘。为了解决这一问题,很多朋友会选择很便捷的方法——使用专业的NTFSforMac读......
  • 128.最长连续序列
    题干给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nu......
  • 贪心算法|376.摆动序列
    力扣题目链接classSolution{public:intwiggleMaxLength(vector<int>&nums){if(nums.size()<=1)returnnums.size();intcurDiff=0;intpreDiff=0;intresult=1;for(inti=0;i<nums.size(......
  • P4551 最长异或路径 题解
    题目链接:最长异或路径看到树上路径问题,且是异或和这种,先思考树上前缀和转化为前缀和问题。如果我们预处理出\(pre[curr]\)表示\(curr\)这个点到根的前缀异或值,那么很显然我们路径的两个点\(u\)与\(v\)的\(pre[u]\opluspre[v]\)和传统的加法的树上前缀和并不一样,因为异......
  • ANSI 转义序列(ANSI Escape Sequences)
    本文来自GithubGistfrom"fnky/ANSI.md"。下面是笔者翻译版本。持续更新中。ANSI转义序列标准Esc代码以Escape为前缀:Ctrl快捷键:^[八进制:\033Unicode:\u001b十六进制:\x1B十进制:27后面跟着命令,有时用左方括号([)分隔,称为控制序列引导码(CSI),后面可选地跟着......
  • 和为给定数(二分法)
    题目: 描述给出若干个整数,询问其中是否有一对数的和等于给定的数。输入共三行:第一行是整数n(0<n<=100,000),表示有n个整数。第二行是n个整数。整数的范围是在0到10^8之间。第三行是一个整数m(0<=m<=2^30),表示需要得到的和。输出若存在和为m的数对,输出两个整数,小的在......
  • 代码随想录算法训练营DAY18|C++二叉树Part.5|513.找树左下角的值、112. 路径总和、113
    文章目录513.找树左下角的值层序-迭代遍历前中后序-递归遍历思路伪代码CPP代码112.路径总和、113.路径总和II112.路径总和思路伪代码实现CPP代码113.路径总和II思路伪代码实现CPP代码实现106\105.从中(前)序与后(中)序遍历序列构造二叉树106.从中序与后序遍历序列......
  • pdffactory pro 8注册码序列号下载 附教程
    PdfFactoryPro可以说是一款行业专业且技术领先的的PDF虚拟打印机软件。其不仅占用系统内存小巧,功能强大,可支持用户无需使用Acrobat来创建AdobePDF即可以进行PDF组件的创建和打印。同时,现在全新的PdfFactoryPro8也正式上线来袭,全面新增添加了如书签、作业订购、信头和自动电......
  • 操作系统综合题之“给进程数和资源数,判断是否安全状态和列出安全序列”
    一、问题:若有3个进程共享9个资源,且当前资源分配情况如下进程已占资源数最大需求数P126P236P315 请回答以及下问题1.目前系统是否处于安全状态?2.如果是,给出进程执行的安全序列,如果不是,请说明理由 二、参考答案1.目前处于安全状态2.安全序列为:P......