[洛谷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]切蛋糕的主要内容,如果未能解决你的问题,请参考以下文章