POJ 2823(Sliding Window)

来源:互联网 发布:数据库监听 编辑:程序博客网 时间:2024/05/16 14:08

今天学习了下单调队列,在网上搜到一篇讲单调队列很不错的博客http://xuyemin520.is-programmer.com/posts/25964 ,单调队列顾名思义就是队列里的元素要单调,怎样维护单调性呢?以上述题目的要求为例。

1.首先看插入元素:为了保证队列的递减性,我们在插入元素v的时候,要将队尾的元素和待插入的val比较,如果队尾的元素不大于val,则删除队尾的元素,然后继续将新的队尾的元素与val比较,直到队尾的元素大于val,这个时候我们才将v插入到队尾。


2.那么队首的元素什么时候删除呢?由于我们只需要保存i的前k-1个元素中的最大值,所以当队首的元素的索引或下标小于 i-k+1的时候,就说明队首的元素对于求f(i)已经没有意义了,因为它已经不在窗里面了。所以当index[队首元素]<i-k+1时,将队首 元素删除。


下面是代码,用G++ TLE,C++才能过

#include <deque>#include <queue>#include <cstdio>#define POB pop_back#define PUB push_back#define POF pop_frontusing namespace std;const int N = 1000010;struct node{int idx, val;}num[N];int main(){int n, i, k;while(~scanf("%d%d", &n, &k)){queue<int> minQue, maxQue;deque<node> down, up;for(i = 1;i <= n;i++){scanf("%d", &num[i].val);num[i].idx = i;}for(i = 1;i <= k - 1;i++){//单调递减 while(!down.empty()&&down.back().val < num[i].val)down.POB();down.PUB(num[i]);//单调递增while(!up.empty()&&up.back().val > num[i].val)up.POB();up.PUB(num[i]); }for(i = k;i <= n;i++){/**维护递减单调队列**/ while(!down.empty()&&down.back().val < num[i].val)down.POB();down.PUB(num[i]);while(!down.empty()&&down.front().idx < i - k + 1)down.POF();maxQue.push(down.front().val);/**维护递增单调队列**/  while(!up.empty()&&up.back().val > num[i].val)up.POB();up.PUB(num[i]);while(!up.empty()&&up.front().idx < i - k + 1)up.POF();minQue.push(up.front().val);}while(!minQue.empty()){printf("%d ", minQue.front());minQue.pop();}printf("\n");while(!maxQue.empty()){printf("%d ", maxQue.front());maxQue.pop();}printf("\n");}return 0;}


原创粉丝点击