【算法竞赛模板】单调队列与单调栈

news2024/11/13 7:56:15

【算法竞赛模板】单调队列与单调栈

  • 一、概念解析
  • 二、单调栈
  • 三、单调队列

在这里插入图片描述

一、概念解析

  • 单调栈:具有单调(递增或递减)性质和栈性质的数据结构
        时间复杂度为 O(n)
  • 单调队列:具有单调(递增或递减)性质和队列性质的数据结构
        时间复杂度可以是O(1)、O(logn)、O(n)

两者的区别:
  单调队列其实是单调栈的一个plus版本,或者说是具有[l, r]区间性质的单调栈(单调栈一般来说是[0, r]类型的)。
  换句话说,对于单调栈能做出来的题目,基本上单调队列也能操作出来,而且请注意一点,单调队列适用范围更加广阔。
  题外话,单调队列是动态规划算法一个必备的优化手段,在大公司面试题目中频频出现。

二、单调栈

  在栈顶push一个元素时,为了维护栈的单调性,需要在保证将该元素插入到栈顶后整个栈满足单调性的前提下弹出最少的元素。
  为什么是最少呢?如下例子,如果是最多的话,插入元素14时,我们还可以弹出元素81,这不符合我们想要的结果。

在这里插入图片描述

int stk[N];		// 数组stk存的是元素的下标
int tt = 0;		// 栈顶
for (int i = 1; i <= n; i++) {
	while (tt && check(stk[tt], i)) tt--;	// check意为判断栈顶何时出栈,while可以不止出栈一个元素
	stk[++tt] = i;
	......									// 其他按题目要求实现
}

👉 单调栈练习题:点我跳转👈
   👇练习题AC代码👇

#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
int h[N], v[N], stk[N], sum[N];
int n;

int main(){
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d%d", &h[i], &v[i]);
	
	int tt = 0;
	for (int i = 1; i <= n; i++) {
		while (tt && h[stk[tt]] <= h[i]) {	// 如果栈不空,并且新元素的高度比栈顶的大,将栈顶元素出栈
			sum[i] += v[stk[tt]];
			tt--;
		}
		sum[stk[tt]] += v[i];				// 因为第i个元素要入栈,根据题意加上相应能量
		stk[++tt] = i;						// 元素i入栈
	}
	
	int ans = 0;
	for (int i = 1; i <= n; i++) ans = max(ans, sum[i]);
	printf("%d", ans);
}

三、单调队列

  单调队列对于任何一个数而言,只会在队列中出现一次,一旦这个数对于最后答案没有贡献了就会及时地将它删除。单调队列限制只能从队尾插入,但能从两端删除(双端队列),队列中保持单调性。对于一个数而言,新插入的数是具有潜力的并且自身价值比它还高的,那么它就出队。

int q[N];	// 数组q存的是元素的下标
int hh = 1, tt = 0;	// 队头、队尾
for (int i = 1; i <= n; i++) {
	while (hh <= tt && check_out(q[hh])) hh++;		// check_out判断队头是否超出队列长度,while可以不止出队一个元素
	while (hh <= tt && check(q[tt], i)) tt--;		// check判断队尾何时出队
	q[++tt] = i;									// 队尾重新指向下标
	......											// 其他按题目要求实现
}

  check_outcheck是我们需要根据题意去实现的,如下练习题可以帮助更好掌握单调队列
👉二分+单调队列练习题:点我跳转 👈
   👇练习题AC代码👇

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int n, s, t;
int nums[N], q[N];
double sum[N];

// 对当前为i的这个位置,设前t个前缀和最小的一个位置为j
// 然后sum[i]-sum[j]便是前缀和最大的那一个
bool check(double mid)
{
	for (int i = 1; i <= n; i++)
		sum[i] = sum[i-1] + nums[i] - mid;

	int hh = 1, tt = 0;
	for (int i = s; i <= n; i++) {
		while (hh <= tt && i-q[hh] > t) hh++;
		// 单调队列维护最优值,根据题意,显然sum[a]<=sum[b]&&a>b说明第i个没什么用
		while (hh <= tt && sum[q[tt]] > sum[i-s]) tt--;
		q[++tt] = i-s;
		// 队首是最小的,前缀和最大便是sum[i]-sum[q[hh]]
		// 但是这个序列长度可能大于T,所以才有前面的i-q[hh] > t
		if (hh <= tt && sum[i]-sum[q[hh]] >= 0) return true;
	}
	return false;
}

int main(){
	cin >> n >> s >> t;
	for (int i = 1; i <= n; i++) scanf("%d", &nums[i]);
	double l = -1e4, r = 1e4;
	while (r - l > 1e-4) {
		double mid = (l + r) / 2;
		if (check(mid))  l = mid;
		else r = mid;
	}
	printf("%.3f\n", l);
}



路漫漫其修远兮,吾将上下而求索

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

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

相关文章

R22-11 《Specification of Time Synchronization》文摘

1 Introduction and functional overview【功能】Time Synchronization between different applications and/or ECUs【目的】be able to track such events in time or to trigger them at an accurate point in time.【方式】ATime Synchronization APIis offered to the App…

webpack基础理解

webpack基础理解 webpack就是将不同格式的文件打包成浏览器能够执行识别的文件 首先创建一些文件 npm init -y 初始化文件 生成一个配置文件package.json 这里如果直接打开静态文件引入main 他会提示你import引入这种模块化语法有问题浏览器并不能直接识别&#xff0c;这时就…

计算机组成原理 第四章笔记记录

为笔记记录&#xff0c;会有个人的理解在里面&#xff0c;若有错误请指出&#xff0c;看到了就改&#xff0c;视频链接 指令格式 指令和指令集的定义 指令:指示计算机执行某种操作的命令,是计算机运行的最小功能单位 指令集:一台计算机的所有指令的集合构成该计算机的指令系统…

微信小程序【获取用户昵称头像和昵称(附源码)】

获取用户昵称头像和昵称 wx.getUserProfile bindgetuserinfo 登录过程 前端源码&#xff1a;https://pan.baidu.com/s/1uz2Gm2FMB-8RFVkhlHY3kQ 提取码&#xff1a;zb4w 后端源码&#xff1a;https://pan.baidu.com/s/1iPpLrXzWnpAsk5UsfKesGw 提取码&#xff1a;8bwm 小程…

Java poi之word文本图片内容提取

目录结构前言文档准备引入Maven依赖代码块提取结果验证孤勇者提取结果青鸟提取结果对比前言 应公司需求&#xff0c;需实现以下功能 word文本内容的替换&#xff1b;word文本内容的提取&#xff1b;word文档中图片的提取存放 此文章将使用Apache POI实现Word文档中文本内容及…

2023-2-3 刷题情况

二叉树着色游戏 题目描述 有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中&#xff0c;给出二叉树的根节点 root&#xff0c;树上总共有 n 个节点&#xff0c;且 n 为奇数&#xff0c;其中每个节点上的值从 1 到 n 各不相同。 最开始时&#xff1a; 「一号」玩家从 …

BIGEMAP GIS Office添加离线地图

BIGEMAP GIS Office添加离线地图发布时间&#xff1a;2019-01-04 版权&#xff1a;BIGEMAP添加离线地图相关应用&#xff1a;搭建 离线地图 二次开发目的&#xff1a;搭建内网地图服务器&#xff0c;内网中可多人访问的地图服务&#xff0c;无需上网工具下载&#xff1a;1、BIG…

2023年企业必不可少的私域运营系统

随着人口红利消失、流量越来越贵、公域转化越来越难&#xff0c;2023年&#xff0c;能够提升用户全生命周期的私域运营&#xff0c;已经成为企业不得不做的事。 面对这种情况&#xff0c;企业必须要引入一款专业且高效的私域运营利器&#xff0c;来实现高效率私域运营管理。快…

二叉树层次遍历的C语言实现

二叉树 树是n个节点的有限集 每个节点事多有两颗子树的树称为 二叉树 二叉树的层次遍历 使用队列的数据结构&#xff0c;从树的根结点开始&#xff0c;依次将其左孩子和右孩子入队。而后每次队列中一个结点出队&#xff0c;都将其左孩子和右孩子入队&#xff0c;直到树中所有结…

Linux——死锁概念介绍和解决方式

目录 一.死锁概念介绍 二.死锁的解决方式 &#xff08;一&#xff09;.预防死锁 方式一&#xff1a;不请求 方式二&#xff1a;强制剥夺资源 方式三&#xff1a;线性分配资源 &#xff08;二&#xff09;.避免死锁&#xff1a;银行家算法 总体流程 安全性检查&#xf…

C语言---冒泡排序和快速排序

文章目录前言一、冒泡排序1.简介2.算法思路3.代码实现二、快速排序1.简介2.算法思路2.1左右指针法2.2挖坑法2.3前后指针法总结前言 交换排序有冒泡排序和快速排序这两种&#xff0c; 基本思想&#xff1a;所谓交换&#xff0c;就是根据序列中两个记录键值的比较结果来对换这两…

多目标跟踪:文献综述

文章目录摘要1、简介1.1、与其他相关综述的区别1.2、贡献1.3、综述的结构1.4. 外延2、 MOT问题2.1、问题公式化2.2、MOT的分类2.2.1、初始化方法2.2.2、处理方式2.2.3、输出类型2.2.4. 讨论3、MOT的组成3.1、外观模型3.1.1、视觉表征3.1.2. 统计测量3.2、运动模型3.2.1. 线性运…

安装httprunner manager遇到的坑

安装httprunner manager参考博客&#xff1a;https://www.cnblogs.com/MrqiuS/p/12944481.html安装mysqlclient报错Collecting mysqlclient1.3.12Downloading https://mirrors.aliyun.com/pypi/packages/6f/86/bad31f1c1bb0cc99e88ca2adb7cb5c71f7a6540c1bb001480513de76a931/m…

maven利用springboot的配置文件进行多个环境的打包

在Spring Boot中多环境配置文件名需要满足application-{profiles.active}.properties的格式&#xff0c;其中{profiles.active}对应你的环境标识&#xff0c;可以随意命名&#xff0c;但要与pom文件中环境标识一样。至于哪个具体的配置文件会被加载&#xff0c;需要在applicati…

Docker系列 01

前言 学完这篇文章&#xff0c;你会知道Docker是什么&#xff1f;解决了什么问题以及如何安装Docker。在后续的系列文章中&#xff0c;我们会陆续介绍Docker的常用命令、镜像原理、Dockerfile以及网络管理等&#xff0c;让你对Docker有较为系统的认知&#xff0c;持续关注吧。 …

多继承的运用

//在封装一个领导类&#xff08;Leader&#xff09;:包括受保护成员&#xff1a;岗位、工资&#xff0c;完成其相关函数及show//由以上两个类共同把派生出学生干部类&#xff1a;引入私有成员&#xff1a;管辖人数&#xff0c;完成其相关函数以及show函数//在主程序中&#xff…

一刷代码随想录——动态规划

1.理论基础如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#xff0c;贪心没有状态推导&#xff0c;而是从局部直接选最优的。对于动态规划问题&#xff0c;我将拆解…

24考研——高等数学的基础概念定理(一)——第一章|函数、极限、连续

今天考试&#xff0c;考定理&#xff0c;我是真没想到这些定理&#xff0c;脑袋瓜子嗡嗡的&#xff0c;害&#xff0c;废话少说&#xff0c;直接开干 文章目录一、基础概念定理1.1 收敛数列的性质&#xff08;唯一性、有界性、保号性、数列与子列关系&#xff09;1.2 函数极限的…

一款语文老师写的word办公神级插件

没错&#xff0c;正如题所说&#xff0c;这是一款语文老师开发的word办公神级插件----不坑盒子&#xff0c;小编体验了一下还真是太强大了&#xff01;双击exe文件&#xff0c;选择任意安装目录即可开始安装如果你的电脑缺少运行库&#xff0c;软件会自动帮你下载安装好安装完成…

QT模块化编程 pro pri 子工程 使用

如果工程过大时&#xff0c;就需要分子模块&#xff0c;Qt 也给我们提供了一种方式 Pri&#xff1b; 这里我们来看看Pri在项目中的使用&#xff0c;项目使用实际上也是很有主要可以模块清晰化&#xff0c;能提高程序的可扩展性。 网上这种写的很多&#xff0c;但少有写明白的&…