单调队列 单调栈
循环输入 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++;

浙公网安备 33010602011771号