单调队列

本文深入探讨了单调队列的概念及其在滑动窗口问题中的应用。通过具体实例,如求解滑动窗口中最大子数组和的问题,阐述了如何利用单调队列维护下标递增及值的递增或递减特性,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很久以前不求甚解的看了一下,然后就没有管了,今天牛客的多校又考到这个点了,遗憾由于根本没有理解单调队列所以没有往这个方向想。

单调队列是一个双端队列,他从头到尾,首先维护了下标的递增,其次根据需要维护了值的递增或递减。

比较经典的就是滑动窗口了。

给定一个大小为k的框,可以框住k个连续的数字,现在问你框不超过k个连续数字使得这些元素和最大。

预处理前缀和sum[],那么我们应该使得区间左端点尽量靠前,且前缀和较小,右端点尽量靠后,且前缀和较大。

于是单调队列就维护了一个下标递增,且s也递增的东西。

对于i=1->n

首先将队头超出位置的元素弹出。

然后判断答案

接下来将队尾比sum[i]大的元素弹出,然后将i加入队尾。

P1714 切蛋糕

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=2e6+7;

int a[maxn];
int q[maxn];
const int inf=0x3f3f3f3f;
int main(){
    int n,k;
    int l=1,r=1;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        a[i]+=a[i-1];
    }
    q[1]=0;
    int res=-inf;
    for(int i=1;i<=n;++i){
        while(l<=r&&q[l]<i-k) ++l;
        res=max(res,a[i]-a[q[l]]);
        while(l<=r&&a[q[r]]>=a[i]) --r;
        q[++r]=i;
    }
    printf("%d\n",res);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值