历史的进程——单调队列

2024-08-23 16:08
文章标签 历史 进程 队列 单调

本文主要是介绍历史的进程——单调队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基本概念

  • 单调队列是一种能保证队列内元素单调性的队列。
  • 与优先队列的不同之处在于,单调队列保持了元素的下标连续性。
  • 复杂度O(n)

具体过程

  • 单调队列在每增加一个元素之前,都先将队列头部大于/小于(具体取决于单调队列的单调性)将要增加的元素的所有元素清除掉,再增加要增加的元素。
  • 由于对于每一个增加的元素都进行了以上操作,每增加完一个元素单调队列内部都保持了单调性。
  • 在保持单调队列的基本结构的同时,往往还要附加一些操作,根据题意进行即可。

注意事项

  • 有时候单调队列的内存空间需要重复利用,因此我们可以每次声明l,r,并使得l=r=1,即可保证内存空间的重复利用。

例题

1.最大子序和

输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。

题目地址

利用前缀和相关的知识,我们知道题意是要维护一个长度不超过m的单调队列,并保存单调队列队首-队尾的最大值。

#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=1000010,INF=2e9;
int a[MAXN],s[MAXN];
int q[MAXN];//queue
int main(){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int tmp;scanf("%d",&tmp);a[i]=tmp;s[i]=s[i-1]+a[i];}int l,r;l=r=1,q[1]=0;//因为可以仅有一个元素,所以s[1]-s[0]=s[1]int ans=-INF;for(int i=1;i<=n;i++){while(l<=r&&q[l]<i-m)l++;//因为可以仅有一个元素,所以这里用<=ans=max(ans,s[i]-s[q[l]]);while(l<=r&&s[q[r]]>s[i])r--;q[++r]=i;}cout<<ans<<endl;return 0;
}

2.环路运输

在一条环形公路旁均匀地分布着N座仓库,编号为1~N,编号为 i 的仓库与编号为 j 的仓库之间的距离定义为 dist(i,j)=min⁡(|i-j|,N-|i-j|),也就是逆时针或顺时针从 i 到 j 中较近的一种。每座仓库都存有货物,其中编号为 i 的仓库库存量为 A_i。在 i 和 j 两座仓库之间运送货物需要的代价为 A_i+A_j+dist(i,j)。求在哪两座仓库之间运送货物需要的代价最大。

题目地址

断环成链后,获得了一个长度为2n的序列。要求的内容是A_i+A_j+(i-j)最大,并且要保证i-j\leq \frac{n}{2}。在满足上述条件的基础上,还要保证单调队列里至少要有两个元素。

这样的话,就要求队列中的每个元素的A_j-j尽量小,那么每次增加新元素时保证单调队列中已有的元素都比新元素小即可。

#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=2000010,INF=2e9;
int a[MAXN],q[MAXN];
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[n+i]=a[i];}int ans=-INF,l,r,mid=n/2;l=r=1,q[1]=1;for(int i=1;i<=2*n;i++){while(q[l]<i-mid)l++;ans=max(ans,a[i]+a[q[l]]+i-q[l]);while(l<=r&&a[i]-i>a[q[r]]-q[r])r--;//保证了队列里起码有一个元素,防止溢出。q[++r]=i;}cout<<ans<<endl;return 0;
}

 

这篇关于历史的进程——单调队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099857

相关文章

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

Linux环境变量&&进程地址空间详解

《Linux环境变量&&进程地址空间详解》本文介绍了Linux环境变量、命令行参数、进程地址空间以及Linux内核进程调度队列的相关知识,环境变量是系统运行环境的参数,命令行参数用于传递给程序的参数,... 目录一、初步认识环境变量1.1常见的环境变量1.2环境变量的基本概念二、命令行参数2.1通过命令编程

Linux之进程状态&&进程优先级详解

《Linux之进程状态&&进程优先级详解》文章介绍了操作系统中进程的状态,包括运行状态、阻塞状态和挂起状态,并详细解释了Linux下进程的具体状态及其管理,此外,文章还讨论了进程的优先级、查看和修改进... 目录一、操作系统的进程状态1.1运行状态1.2阻塞状态1.3挂起二、linux下具体的状态三、进程的

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一