下方没有程序,只有过程~(
因为懒)哪里有问题
很正常,毕竟是个蒟蒻QAQ
1.判断序列连续区间,固定长度(为m)的最值。
问题描述:给定一个序列,长度为。现在需要找到区间长度为m的子区间的最大值/最小值,并依次输出。
洛谷P1886 滑动窗口https://www.luogu.com.cn/problem/P1886
我们就拿最大值举例:
比如这一段序列,规定。
如果传统去枚举,每次遍历个数。时间复杂度是,而单调队列却可以神奇的做到
那单调队列是个什么东西呢??
一个For循环从1~n
- 发现队伍空的,把1入队。
- 3比1大,把1踢走,发现前面没有数了,然后3入队。
- 4比3大,把3踢走,发现前面没有数了,然后4入队。 输出队首:4
- 2比4小,入队。 输出队首:4
- 1比2小,入队。 输出队首:4
- 0比1小,入队。发现队列长度太长了() 于是把队首弹出。 输出队首:2
- 7比0大,把前面所有比他小的都踢走,再把队列长度不符合的踢走。于是输出队首:7
那么答案就是4 4 4 2 7
关键就是,我们始终是在维护一个单调(递减)的队列,并且是一个双端队列(需要从尾部入队/出队和头部出队)。
注意点:
- 始终只有队尾入队
- 手写双端队列会快一点
- 什么时候队首出队,什么时候队尾出队分清(头出是因为长度过了,尾出是因为里面的数不满足现在要求了(他们太弱了需要离开了))
- 该单调队列维护的是一个下标,不是实际的数字!!
- 顺序可以是:尾部出队;入队;头部出队;做一些题目要做的;或者别的顺序
2.判断序列连续区间,不固定长度[S,T]是否存在一个性质。
里面需要二分答案转换一下,然后我们需要解决的问题就是:
给定一个序列,长度为。现在需要判断是否存在区间长度为的连续子区间,使得该子区间的和>0。
洛谷p1419 寻找段落https://www.luogu.com.cn/problem/P1419
那么我们需要统计一段连续子区间的和,就可以变成前缀和的差值来实现。
由于我们是要让越大越好,现在枚举的是i,也就是单调队列里面应该存的是的最小值。
步骤如下:
- 让尾部出队,并且入队:如果当前的比尾部的小,我们就一直尾部出队。然后把这个放进去。
- 头部出队:由于我们的区间是[S,T],所以头部出队的时候就判断区间长度是不是大于T就可以了。
- 判断性质:如果现在的比队首(也就是最小值啦)要大,那就已经符合题目要求了。
完结撒花~
什么?你问我单调队列优化DP呢?
都说了蒟蒻,等我刷完基础DP再说吧~
QAQ