单调队列的实现与应用
来源:互联网 发布:网吧会员软件 编辑:程序博客网 时间:2024/06/05 09:55
单调队列
单调队列引入:
首先看一个例题:
给你一个长度为N的数组,一个长为K的滑动框从最左端滑到最右端,你只可以看到框内的K个数,每次框向右移动一格。请你找出框在各位置的最小值。
样例输入:
8 3
1 3 -1 -3 5 3 6 7
样例输出:
-1 -3 -3 -3 3 3
代码实现:
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int n,m,i,j,k,l,h,t;int a[100000],q[100000],time[1000001];/*a中存储的就是数组中元素的值,q中存储的是单调队列该位置所对应的数组中元素的值,time是保存单调队列该位置所对应的数组中元素进队的时间*/int main(){cin>>n>>k;for (i=1;i<=n;i++) cin>>a[i];h=1;for (i=1;i<=n;i++){while (i-time[h]>=k&&(h<t)) h++;队首元素超出K区间边界,需要剔除。while (t>0&&t>=l&&q[t]>a[i]) t--;//从队尾向前扫描,直到找到一个比a[i]小的。此时相当于把后面的剔除了。因为已经可以确定那些值不会是ans。t++;q[t]=a[i];time[t]=i;if (i>=k) cout<<q[h]<<' ';}}
这个例题充分说明了单调队列是干什么的?来查找不断移动的K区间内的最小(大)值(动态规划中应用广泛)。
单调队列的维护:
1.这里采用了最直接的方法:普通队列实现缓存数组。
进队出队都是O(1),一次查询需要遍历当前队列的所有元素,故O(n)。
2.还可以用堆实现缓存数组
堆顶始终是最小元素,故查询是O(1)。(对q数组用堆来维护)
而进队出队,都要调整堆,是O(log(n))。
单调队列的过程:
查询:单调队列的队头一定最小值,所以查询为O(1)。
进队:进队时,将进队的元素为a[i],从队尾往前扫描,直到找到一个不大于a[i]的元素f[t],把a[i]放在f[t]之后,舍弃f[t]之后的所有元素;如果没有找到,则把a[i]放在队头(该值当前最小)。
出队:出队时,将出队的元素为q[h],从队头向后扫描,直到找到一个‘未老’的元素(即在给定的范围当中),舍弃该元素之前所有的。
每个元素最多进队一次,出队一次,均摊下来仍然是 O(1)。
单调队列实际上是具有单调性的子序列,但这并不是一个真正意义上的队列,在进队和出队时对某段进行反复操作。但是却具有队列的特性。
单调队列和二分,线段树一样是用来优化的一种数据结构。在动态规划中应用较广泛。
0 0
- 单调队列的实现与应用
- 单调队列的应用
- 单调队列的应用
- 单调队列的应用
- 单调队列实现与例题
- HDU3530 单调队列的应用
- 浅谈单调队列的应用
- 队列的实现与应用
- 单调队列应用
- 单调队列 及其应用
- 单调队列及其应用
- 单调队列与单调栈
- 单调栈与单调队列
- 单调栈和单调队列的概念与运用
- 栈与队列-单调栈,单调队列
- Tyvj1305(单调队列简单应用,用list实现)
- 用双端队列实现单调队列
- 单调队列与DP
- 批处理是什么?该怎么建立批处理文件呢?
- IMWeb前端学习笔记——Day6
- 图片加载框架四大之一Picasso 加载 Https 图片的那些套路
- 0410-颜色控制属性
- hdu3068_最长回文串_Manacher(马拉车模板)
- 单调队列的实现与应用
- Oracle ORA-01033: ORACLE initialization or shutdown in progress 错误解决办法
- Keep In Line
- 把排序数组转换为高度最小的二叉搜索树
- ~位图(补充)~
- JAVA设计模式之工厂模式
- 当CPU飙高时,它在做什么
- Max Consecutive Ones
- 这三种研发工程师千万不能招?