单调队列————[USACO09MAR]向右看齐Look Up

 先了解一下单调队列:

   很明显的具有单调性

  分为单调递增和单调递减两种,简单点讲就是维护队头为最大值或者为最小值

(建议采用双向队列  比较好写)

  具体步骤:(这个是单调递减)

     如果队列非空且当前值比队尾元素大,不断删除比该值小的元素,否则直接队尾入队

      

while(!que.empty()&&ma[i]>que.back())
 {
     que.pop_back();
}
 que.push_back(i);

    单调队列的作用::

     1):可以用来维护区间的单调性,用来解决最大或最小的问题

     2):可以用来求一个序列里第一个大于或等于数x的数

    可能还有不知道的地方,敬请指教

看个例题

题意::

     求序列中每一个在其右边的第一个比它大的值,就是向右找寻第一个比他本身大的值,并且储存下来,没找到则得0。

 思路:维护单调递减队列即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn=1e5+5;
 5 int ma[maxn];
 6 deque<int> que;
 7 int c[maxn];
 8 int main()
 9 {
10     int n;
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++)
13     {
14         scanf("%d",&ma[i]);
15     }
16     for(int i=n;i>=1;i--)
17     {
18         while(!que.empty()&&ma[i]>=ma[que.back()])
19         {
20             que.pop_back();
21         }
22         if(que.empty()){
23             c[i]=0;
24         }
25         else{
26             c[i]=que.back();
27         }
28         que.push_back(i);
29     }
30     for(int i=1;i<=n;i++){
31         printf("%d\n",c[i]);
32     }
33     return 0;
34 }

 再推荐大家可以练练手的题:(难度不分先后)

  hdu3530 Subsequence 单调队列入门题

  poj2559 Largest Rectangle in a Histogram

  poj2823 Sliding Window

  洛谷  P1714 切蛋糕  P2032 扫描  P1901 发射站

猜你喜欢

转载自www.cnblogs.com/sj-gank/p/11480137.html
今日推荐