[数据结构学习]单调队列

单调队列,即内部元素相对于比较器有序的队列,可以方便的查询序列中某个连续区间内的最大/最小值

也能在状态转移时优化决策以降低时间复杂度。(嗯,这句是OI-Wiki上说的,作为蒟蒻qwq我并不知道如何优化dp)

比如我们想知道一个长为n的数字序列中每连续k个数中最小的那个数

如果暴力求解的话,遍历从1~n-k+1,复杂度O(n*k),而且需要将每个子序列中的值与其他值进行比较,是比较慢的=-=

对于这个问题就可以维护一个递减的单调队列,同时注意队列中的数字区间不要超过k

维护的方法:

每读入序列中的一个新的数,比较该数与队尾的数的关系

1.若该数大于队尾的数,入队。

2.若概述小于队尾的数,队尾的数出队,再次将该数与队尾的数进行比较。

入队后检查当前队首和队尾两个数所包含的数字区间是否超过k

如果超过则队首出队。

cin>>t;
while(!dq.empty() && dq.back() > t)
    dq.pop_back(), no.pop_back();
dq.push_back(t), no.push_back(i);
while(no.back() - no.front() >= k)
    dq.pop_front(), no.pop_front();

//这里是用deque做容器维护单调队列, no也是一个deque,维护在dq中数字的相应编号(下标)

这样维护的队列的队首元素总是每k个元素中最小的

O(1)即可取出,而每个数最多出队一次入队一次,维护队列的时间复杂度仅为O(n)

原文地址:https://www.cnblogs.com/leafsblogowo/p/12687225.html

时间: 2024-10-14 13:47:27

[数据结构学习]单调队列的相关文章

简单数据结构总结——单调队列

单调队列一般是具有单调性的队列废话 视具体题目而定,单调队列有单调递增和单调递减两种,一般来讲,队列的队首是整个队列的最大值或最小值 单调队列可以解决许多问题,而且可以用来优化DP,但是这里不讲因为我还不会' 下面简单的介绍一下单调队列的实现 具体步骤: 若队列为空,将A[i]从队尾入队 若队列不为空,将比A[i]大的元素都从队尾弹出,然后把A[i]入队 若队列不为空且A[i]大于队尾,则直接从队尾把A[i]入队 实现一般采用双端队列主要因为好写当然也可以自己手写 下面放出代码 1 if(q.e

数据结构学习(循环队列)

1. 尾索引的下一个为头索引时表示队列满,即将队列容量空出一个作为约定 2. 这个在做判断队列满的时候需要注意 (rear + 1) % maxSize == front [满] rear == front [空] package cn.imut; //循环队列 import java.util.Scanner; public class CircleArrayQueueDemo { public static void main(String[] args) { System.out.prin

【bzoj 1414】对称的正方形 单调队列+manacher

Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们排成了一个n行m列的矩阵.通过观察,Orez发现这些数据蕴涵了一个奇特的数,就是矩阵中上下对称且左右对称的正方形子矩阵的个数. Orez自然很想知道这个数是多少,可是矩阵太大,无法去数.只能请你编个程序来计算出这个数. Input 文件的第一行为两个整数n和m.接下来n行每行包含m个正整数,表示Orez得到的矩阵. Output 文件中仅包含一个整数answer

单调队列总结

单调队列 就是保持队列中的元素始终保持单调性,这个数据结构就是单调队列 它的作用就是维护最值.求第一个比i小(大)的数的下标等等 还有个单调栈来着,不过我们可以用一个双端队列就足够了 如果要维护最大值,就用单调递减队列,反之,用递增队列 1.hdu3530 Subsequence 单调队列入门题 这题求的是最大值减去最小值不小于m不大于k的最长长度 这题用单调队列维护最大值和最小值即可 #include<iostream> using namespace std; #define MAX 10

数据结构学习之循环队列(顺序存储)

[摘要]队列特性:先进先出(FIFO)--先进队列的元素先出队列.来源于我们生活中的队列(先排队的先办完事). 这样有个缺陷,空间利用率不高,所以我们直接学习循环队列(基于连续内存的). (1)设计队列数据结构 typedef struct _QUEUE_NODE { int* pData; int length;//队列长度 int head ;//队头指针 int tail;//队尾指针 int count;//队列元素当前个数 }QUEUE_NODE; (2)申请队列内存 QUEUE_NO

【NOIP数据结构专项】单调队列单调栈

[洛谷P1901 ]发射站 http://www.luogu.org/problem/show?pid=1901 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收

【算法学习笔记】53.单调队列的简单应用 SJTU OJ 1034 二哥的金链

1034. 二哥的金链 Description 一个阳光明媚的周末,二哥出去游山玩水,然而粗心的二哥在路上把钱包弄丢了.傍晚时分二哥来到了一家小旅店,他翻便全身的口袋也没翻着多少钱,而他身上唯一值钱的就是一条漂亮的金链.这条金链散发着奇异的光泽,据说戴上它能保佑考试门门不挂,RP++.好心的老板很同情二哥的遭遇,同意二哥用这条金链来结帐.虽然二哥很舍不得这条金链,但是他必须用它来付一晚上的房钱了. 金链是环状的,一共有 N 节,老板的要价是 K 节.随便取下其中 K 节自然没问题,然而金链上每一

数据结构之单调栈单调队列模板

单调栈 int rear=0; for(int st=1;st<=N;st++) { while(rear>0&&H[que[rear]]>=H[st]) --rear; if(rear==0) le[st]=0; else le[st]=que[rear]; que[++rear]=st; } 单调队列 int que[maxn],elem[maxn]; int front=1,rear=0; for(int i=1;i<K;i++) { while(rear&g

学习笔记:单调队列

转自:http://apps.hi.baidu.com/share/detail/34010558 [单调队列]在解一个序列某个区间段的最值问题,我们可以用到单调队列来解决.  比如poj2823 Sliding Window 就是一个很好的例子:给定一个序列,要求序列中固定长度为k 的区间中的最大值和最小值.  [原理]单调队列维护的是区间最值:  1.最大值的维护:          比如我们要维护一个区间为k的最大值的单调队列,由于新插入 的节点他的“生命力”肯定比原先已经在队列中的元素“