一篇博客需要一个引领全文的话:
当一个人比你小还比你强,你就该考虑退役了 !\large\text{当一个人比你小还比你强,你就该考虑退役了 !}当一个人比你小还比你强,你就该考虑退役了 !
− When someone is younger than you and better than you, it′s time to consider retirement! −\small{-\ When\ someone\ is\ younger\ than\ you\ and\ better\ than\ you,\ it's\ time\ to\ consider\ retirement!\ -}− When someone is younger than you and better than you, it′s time to consider retirement! −
这就是单调队列的精髓。
原理:
单调队列使用一个队列来实现。
单调队列就是确定了一个框后,从头开始,不断往右滑。通过这个窗口,我们就可以知道此窗口内的极值(max,minmax,minmax,min 之类的)。
注:队列里面存的是元素下标,而不是元素本身。
实现:
每次遍历到一个新元素时,从尾段(ttt)开始把比它弱的都干掉(t−−t--t−−),然后再把自己存进去(q[ ++t ]=pq[\ ++t\ ]=pq[ ++t ]=p)。如果头端超出了窗口,就剪掉(h++h++h++)。
这样一来,队列的头端就一定是当前这个窗口的极值(q[ h ]q[\ h\ ]q[ h ])。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+10;
int n,l,r,a[N],f[N],h=1,t=1,q[N],ans=-0x3f;
signed main(){
cin>>n>>l>>r;
for(int i=0;i<=n;i++)cin>>a[i];
memset(f,-0x4f,sizeof(f));
f[0]=0;
for(int i=l;i<=n;i++){
while(h<=t&&f[i-l]>=f[q[t]])t--;
q[++t]=i-l;
while(q[h]+r<i)h++;
f[i]=a[i]+f[q[h]];
if(i>n-r)ans=max(ans,f[i]);
}
cout<<ans<<"\n";
return 0;
}
本文介绍了单调队列这一数据结构的原理和用途,主要在于找到窗口内的极值,如最大值或最小值。在遍历过程中,通过更新队列来保持其单调性,从而高效地处理动态范围查询。文中给出了C++的代码示例,展示了如何利用单调队列解决特定问题。
1530

被折叠的 条评论
为什么被折叠?



