切蛋糕
题目描述
今天是小 Z 的生日,同学们为他带来了一块蛋糕。这块蛋糕是一个长方体,被用不同色彩分成了 n n n 个相同的小块,每小块都有对应的幸运值。
小 Z 作为寿星,自然希望吃到的蛋糕的幸运值总和最大,但小 Z 最多又只能吃 m ( m ≤ n ) m(m\le n) m(m≤n) 小块的蛋糕。
请你帮他从这 n n n 小块中找出连续的 k ( 1 ≤ k ≤ m ) k(1 \le k\le m) k(1≤k≤m) 块蛋糕,使得其上的总幸运值最大。
形式化地,在数列 { p n } \{p_n\} {pn} 中,找出一个子段 [ l , r ] ( r − l + 1 ≤ m ) [l,r](r-l+1\le m) [l,r](r−l+1≤m),最大化 ∑ i = l r p i \sum\limits_{i=l}^rp_i i=l∑rpi。
输入格式
第一行两个整数 n , m n,m n,m。分别代表共有 n n n 小块蛋糕,小 Z 最多只能吃 m m m 小块。
第二行 n n n 个整数,第 i i i 个整数 p i p_i pi 代表第 i i i 小块蛋糕的幸运值。
输出格式
仅一行一个整数,即小 Z 能够得到的最大幸运值。
样例 #1
样例输入 #1
5 2
1 2 3 4 5
样例输出 #1
9
样例 #2
样例输入 #2
6 3
1 -2 3 -4 5 -6
样例输出 #2
5
提示
数据规模与约定
- 对于 20 % 20\% 20% 的数据,有 1 ≤ n ≤ 100 1\le n\le100 1≤n≤100。
- 对于 100 % 100\% 100% 的数据,有 1 ≤ n ≤ 5 × 1 0 5 1\le n\le5\times 10^5 1≤n≤5×105, ∣ p i ∣ ≤ 500 |p_i|≤500 ∣pi∣≤500。
保证答案的绝对值在 [ 0 , 2 31 − 1 ] [0,2^{31}-1] [0,231−1] 之内。
#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
#include<deque>
#define debug cout<<"ok"<<endl
typedef long long ll;
const int maxn=1e7+10;
const int mod=1e9+7;
using namespace std;
int ans=-233333333,n,m,a,sum[maxn];
deque<int>q;
int main() {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%d",&a);
sum[i]=sum[i-1]+a;
}
q.push_back(0);
for(int i=1; i<=n; i++) {
while(q.front()+m<i)
q.pop_front();
ans=max(ans,sum[i]-sum[q.front()]);
while(!q.empty()&&sum[q.back()]>=sum[i])
q.pop_back();
q.push_back(i);
}
printf("%d\n",ans);
return 0;
}
}