单调队列学习小结
对单调队列的分析和说明就不赘述了,贴几个博客http://blog.csdn.net/justmeh/article/details/5844650 http://blog.csdn.net/justmeh/article/details/5844650
一般来说一个单调队列需要具备一个数组,它的头尾,以及尾部添加、首部剔除和取首部元素。
对于大部分DP题,队列插入次数不会超过枚举的状态数,所以直接开一个数组,让队列窗口在里面滑动即可,不需要使用链表等方式节约空间。
对于许多DP问题,i状态需要从前面的0~i-1状态中选取一个最优值进行转移,而如果其最优值可单调表示(决定首部插入时能不能排除若干队列元素),且队列首部能根据i而决定是否仍能使用(决定了尾部是否能排除),就可以用单调队列优化掉每次的查找。
单调队列的大致结构如下,括号中的内容以及参数细节需要根据题目设定及补充。
struct MonoQue { LL arr[1000005]; LL head,tail; void init() { head=tail=0; } void add(LL p) { while(tail>head) { if() tail--; else break; } arr[tail++]=p; } void del(LL i) { while(tail>head) { if() head++; else break; } } LL g() { return arr[head]; } };