[洛谷P1714]切蛋糕

Posted Mrsrz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[洛谷P1714]切蛋糕相关的知识,希望对你有一定的参考价值。

题目大意:给你n个数,要你求一段长度不超过k的、和最大的连续子序列,问你最大的和是多少。

解题思路:单调队列+前缀和优化。

可以发现,i到j的和与k到j的和,当j变化时,这两个和的相对大小关系是不变的。

我们用单调队列保存与当前第i个位置距离小于k(等于则不能加到)的位置,并让这个位置加到i的和单调递减。

这样就能保证每次从队头弹出时,之后的和仍是最大。

求一段连续序列的和就用到前缀和优化。

总时间复杂度$O(n)$。

C++ Code:

#include<cstdio>
#include<cctype>
#define N 500005
int n,k,a[N],sa[N],q[N<<1],h,t;
inline int max(int a,int b){return a<b?b:a;}
inline int readint(){
    char c=getchar();
    bool b=false;
    for(;!isdigit(c);c=getchar())b=c==‘-‘;
    int d=0;
    for(;isdigit(c);c=getchar())
    d=(d<<3)+(d<<1)+(c^‘0‘);
    return b?-d:d;
}
int main(){
    n=readint(),k=readint();
    sa[0]=0;
    for(int i=1;i<=n;++i)sa[i]=sa[i-1]+(a[i]=readint());
    int ans=max(0,a[1]);
    if(k==1){
        for(int i=1;i<=n;++i)ans=max(ans,a[i]);
        printf("%d\n",ans);
        return 0;
    }
    q[1]=h=t=1;
    for(int i=2;i<=n;++i){
        while(q[h]+k<=i)++h;
        while(h<=t&&a[i]>sa[i]-sa[q[t]-1])--t;
        q[++t]=i;
        ans=max(ans,sa[i]-sa[q[h]-1]);
    }
    printf("%d\n",ans);
    return 0;
}

 

以上是关于[洛谷P1714]切蛋糕的主要内容,如果未能解决你的问题,请参考以下文章

P1714 切蛋糕

单调队列P1714 切蛋糕

luogu P1714 切蛋糕 |单调队列

P1714切蛋糕(不定区间最值)

Luogu P1714切蛋糕(面向对象编程首次尝试?)

(c语言)切蛋糕问题