单调队列,顾名思义是指队列内的元素是有序的,队头为当前的最大值(单调递减队列)或最小值(单调递增序列),以单调递减队列为例来看队列的入队和出队操作:

1、入队:

如果当前元素要进队,把当前元素和队尾元素比较,如果当前元素小于队尾元素,那么当前元素直接进队,如果当前元素大于队尾元素,那么队尾出队,将当前元素和新的队尾再做比较,直到当前元素大于队尾元素或者队列为空。单调队列只能在队尾插入元素,队尾和队头都可以删除元素。

2、出队:

出队直接取队头即可,因为用单调队列就是为了取最值,而队头就是最值。

例子:将数组a[] = {3, 5, 2, 8, 1, 4, 7}依次入队,并保证队列为一个 单调递减 队列。

  • 3入队,队列为空直接入队,队列元素为:3;
  • 5入队,5和队尾比较,5大于3,3出队,队为空,5入队,队列元素为:5;
  • 2入队,2和队尾比较,2小于5,直接入队,队列元素为:5,2;
  • 8入队,8和队尾比较,2出队,8再和队尾比较,5出队,队为空,8入队,队列元素为:8;
  • 1入队,...,队列元素为:8,1;
  • 4入队,...,队列元素为:8,4;
  • 7入队,...,队列元素为:8,7。
实例应用:
1、给定一个数组a[]和一个长度为k的滑动窗口,该窗口从最左端移到最右端,找出窗口在每个位置是的最大值。
     例如:a[] = {7, 3, 2, 5, 6},k = 3。我们可以维护一个单调递减队列,这样对于每个位置,当前队列的队头就是最大值,只不过在入队的时候要检查一下队头的下标是否已经超出窗口的范围,如果超出就删除队头元素即可。为了方便写代码,单调队列很多时候保存的是下标,而不是数值本身。
  • i = 0,初始队列为空,7入队,队列为:{ 0(7) }, (0为下标,括号为下标对应的值) ,窗口区间为[0],最大值为队头a[0] = 7;
  • i = 1,队头下标没有超出k, 3入队,队列为:{ 0(7), 1(3) },窗口区间为[0,1],最大值为队头a[0] = 7;
  • i = 2,队头下标没有超出k,2入队,队列为:{ 0{7), 1(3), 2(2) },窗口区间为[0,1,2],最大值为队头a[0] = 7;
  • i = 3,队头下标为0超出k,删除队头,5入队,队列为:{ 3(5) },窗口区间为[1,2,3],最大值为队头a[3] = 5;
  • i = 4,队头下标没有超出k,6入队,队列为:{ 4(6) },窗口区间为[2, 3, 4],最大值为队头a[4] = 6;
  • 窗口继续向右滑动,如果当前队头下标超出范围就删除队头,然后去队头,没有超出范围就直接取队头。
这样整个算法就是O(n)的。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,a[2000010];
int q[2000010],h=1,t=1;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
printf("0\n");
q[1]=1;
for(int i=2;i<=n;i++)
{
printf("%d\n",a[q[h]]);
if(q[h]<=i-m)
h++;
while(a[i]<=a[q[t]]&&t>=h)
t--;
t++;
q[t]=i;
}
return 0;
}

单调队列——求m区间内的最小值的更多相关文章

  1. 洛谷1440 求m区间内的最小值

    洛谷1440 求m区间内的最小值 本题地址:http://www.luogu.org/problem/show?pid=1440 题目描述 一个含有n项的数列(n<=2000000),求出每一项 ...

  2. 求m区间内的最小值

    洛谷P1440 求m区间内的最小值 ............................................................................... 以上 ...

  3. P1886 滑动窗口&&P1440 求m区间内的最小值

    声明:下面这两个题就不要暴力了,学一学单调队列吧 推荐博文:https://www.cnblogs.com/tham/p/8038828.html 单调队列入门题 P1440 求m区间内的最小值 题目 ...

  4. 洛谷 P1440 求m区间内的最小值

    传送门 思路 由于数据范围很大,所以使用单调队列,和滑动窗口这道题类似 首先第一个数输出\(0\),因为第一个数之前没有数 然后通过样例我们发现,最后一个数并没有派上什么用场,所以循环\(n-1\)轮 ...

  5. LG1440 求 m 区间内的最小值

    题目描述 一个含有 \(n\) 项的数列 (\(n≤ 2000000\)),求出每一项前的 \(m\) 个数到它这个区间内的最小值.若前面的数不足 \(m\) 项则从第 \(1\) 个数开始,若前面没 ...

  6. 【题解】P1440 求m区间内的最小值

    求m区间内的最小值 题目描述: 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 分析: 读题之 ...

  7. 洛谷 1440 求m区间内的最小值

    洛谷  1440 求m区间内的最小值 题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. ...

  8. P1440 求m区间内的最小值--洛谷luogu

    题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...

  9. 洛谷—— P1440 求m区间内的最小值

    https://www.luogu.org/problemnew/show/P1440 题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的 ...

随机推荐

  1. Cocos2D:塔防游戏制作之旅(十)

    最终,draw方法显示这些路径点被放置在哪里,并且绘制出路径点之间的连线,它们仅仅被用作调试.一个成品游戏不应该绘制敌人的路径 - 那对于玩家来说太过容易了! 创建路径点的列表.打开HelloWorl ...

  2. windbg分析运行在64位环境下的32位程序的dump

    windbg命令如下 1.   .load wow64exts 2.   !sw 3.   ~* kvnf

  3. 小试ImageMagik——使用篇

    ===================================================== ImageMagick的使用和开发的文章: 小试ImageMagik--使用篇 小试Imag ...

  4. iOS中 FMDB第三方SQLite数据库 UI_20

    1.什么是FMDB? FMDB是iOS平台下SQLite数据库,只不过它是OC方式封装了C语言的SQLite语句,使用起来更加面向对象 2.FMDB的优点:1.使用起来更加面向对象; 2.对比苹果自带 ...

  5. 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)

    . 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...

  6. C#之面向对象

    话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天下,曹操大悦,于是晏众文武,在酒席间,曹操诗兴大发,不觉吟道:"喝酒唱歌,人生真爽" ...

  7. nginx 编译增加新的模块

    原已经安装好的nginx,现在需要添加一个未被编译安装的模块: nginx -V 可以查看原来编译时都带了哪些参数 原来的参数:--prefix=/app/nginx 添加的参数: --with-ht ...

  8. UE4 动画系统

    1.      准备一套带动作的模型,并导入UE4 2.      新建一个动画蓝图,右键->Animation->AnimationBlueprint,选择继承AnimationInst ...

  9. gcc学习(一)[第二版]

    gcc简介 1. gcc是GNU Compiler Collection的缩写.最初是作为C语言的编译器(GNU C  Compiler),作者为Richard Stallman,是GNU项目的奠基者 ...

  10. UML之包图

    包图是UML中用类似于文件夹的符号表示的模型元素的组合,系统中的每个元素都只能为一个包所有,一个包可嵌套在另一个包中,使用包图可将相关元素归入一个系统,一个包中包含附属包.图表或单个元素.简单的来说, ...