单调队列 单调栈

循环输入 a[i]  当满足条件的时候调整栈(队列)的元素,使其具有单调性  

当我们需要在后面找一个比当前位置的数还要大的数的时候,保持栈的递减性     因为找到这个大数的时候要进行一系列的操作,会使这个大数的下标移到栈顶

每遍历到的a[i]都需要先压进栈里面,至于会不会用到,看后面遍历的数会不会把他给弹出来,但是每个遍历的a[i]要有压进栈的过程,这样可以在hea+r<i的时候,让压进去的数据发生作用。

求最近的一个大数       落谷p2947

//用手打栈来写
for
( i=1 ; i<=n; i++){ cin>>a[i]; while ( tail>=head && a[i]>a[s[tail]] ){ f[ s[tail] ]=i;tail--; //f记录最近的 } s[ ++tail ] = i; } for ( i=1 ; i<=n ; i++ ) cout<<f[i]<<endl;
//用stl来写      这个使得如果没有找到比他小的就赋值为n+1
for(i=n;i>=1;i--){ while(!q.empty()&&q.top().h>h[i]) q.pop(); if(!q.empty()) r[i]=q.top().s; else r[i]=n+1; node t; t.h=h[i]; t.s=i; q.push(t); }

 

求前几个中的最值 (自己本身不参与比较)  洛谷 p1440

cin>>a[1];s[head]=1;cout<<0<<endl;
    for ( i=2 ; i<=n ; i++){
        cin>>a[i];
        while ( head<=tail && s[head]+m < i ) head++;
        cout<<a[ s[ head ] ]<<endl; //自己本身不参与比较 
        while ( head<=tail && a[ s[tail] ] > a[i] ) tail--;
        s[ ++tail ] = i;
        
    }

 求包含自己的最值  落谷p2251

双区间的问题  当最小移动距离大于1 的时候,要利用好dp的思想,第i个位置的最大值等于第i-r到i-l的区间里的最大值加a[i];单调队列可以求出第i-r到i-l的区间里的最值问题。

遍历从 i=L开始,这时候相当于所求区间的左端点在a[0]上,区间长度为r,右端点i-L+r包含i。

然后i循环遍历的时候,相当于把数据区间变成0到i-L压进单调栈,当是s[head]+r<i说明区间长度不够,要head++;

posted @ 2021-09-04 09:27  Pan_c  阅读(46)  评论(0)    收藏  举报