单调队列
2015-07-27 15:04
190 查看
单调增或减的队列,作用于广告印刷、动态规划等。
(单调增为例)
1、入队时,从队尾向前扫描,直到找到队内某个元素小于它,把它放在这个元素的后面,将它作为队尾,即删除队内比它大的所有元素。
它入队比所要删除的元素晚,证明它的位置一定大于所要删除元素的位置,根据这一点,我们可以推出:
在以后的选择中,当所要删除元素的位置在所要找的区间时,它也一定在所要找的区间内。
而它又比所要删除元素小,所以它一定比所要删除元素更优。
所以它的入队意味着所要删除的元素已经失去了价值,故可以删除。
2、出队时,如果队首元素的位置不在所要找的区间内,那么就把下个元素作为队首,即删除原队列的队首。
此时下个元素一定在所要找的区间内。
假设上次查找的区间为[a,a+k-1],那么经过上次出队后,队首元素的位置最坏情况下是a,那么它后面的元素的位置一定满足p>=a+1,
所以它后面的元素一定在这次要找的区间[a+1,a+k]中。
(单调增为例)
1、入队时,从队尾向前扫描,直到找到队内某个元素小于它,把它放在这个元素的后面,将它作为队尾,即删除队内比它大的所有元素。
它入队比所要删除的元素晚,证明它的位置一定大于所要删除元素的位置,根据这一点,我们可以推出:
在以后的选择中,当所要删除元素的位置在所要找的区间时,它也一定在所要找的区间内。
而它又比所要删除元素小,所以它一定比所要删除元素更优。
所以它的入队意味着所要删除的元素已经失去了价值,故可以删除。
2、出队时,如果队首元素的位置不在所要找的区间内,那么就把下个元素作为队首,即删除原队列的队首。
此时下个元素一定在所要找的区间内。
假设上次查找的区间为[a,a+k-1],那么经过上次出队后,队首元素的位置最坏情况下是a,那么它后面的元素的位置一定满足p>=a+1,
所以它后面的元素一定在这次要找的区间[a+1,a+k]中。
#define maxn 100000+10 int num[maxn]; int max_que[maxn]; //记录元素的位置 int get_que(int f,int r,int x){ //二分 int mid; while( f <= r ){ mid = ( f + r ) / 2; if( num[max_que[mid]] == num[x] ) return mid; if( num[max_que[mid]] > num[x] ) r = mid - 1; else f = mid + 1; } return r; } int get_que(int f,int r,int x){ //非二分 while( f < r && num[x] <= num[max_que[r]] ) r--; return r; }
相关文章推荐
- ListView 去掉分隔线
- linux程序设计——个人总结
- Apache ActiveMQ消息中间件的基本使用
- Same Tree
- 2.4-yum工具详解
- Android的权限机制总结
- ZOJ 1649 Rescue BFS (搜索)
- VC编程实现色彩空间XYZ与LAB相互转换-----改正版
- getopt函数
- 状态栏隐藏
- HDOJ--PBD
- MyEclipse下编写JSP "Hello World"
- Hiwork实现全端覆盖——联合CSDN和码农周刊给各位送书啦!!
- .NET状态保持(一)
- 2.3-rpm查询
- epoll 或者 kqueue 的原理是什么?
- leetcode 058 —— Length of Last Word
- 基于Web的在线考试系统
- 深入理解JavaScript的闭包特性如何给循环中的对象添加事件
- cocos2dx3.1从零学习(二)菜单、场景切换、场景传值