题目链接 :
https://www.luogu.com.cn/problem/P1714
题目大意:
有 n 块蛋糕,每一块蛋糕有一个幸运值,你最多可以吃 m 块,最少吃 1 块,求最多能获得多少幸运值,本质为 求最大不定长子段和。
思路:
求子段和,容易想到求 前缀和 。
长度为 1 到 m 的区间中最大的子段和可以 转化 为终点的 sum 减去这个区间内最小的 sum,终点的 sum 通过 前缀和 求出,而区间内最小的 sum, 可以通过构造一个递增的单调队列来求解。
求出来每一段区间的 最大不定长字段和 后取最大。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500005;
int n, m, sum[MAXN], p, q[MAXN] = {0}, e = 1, s = 1, maxn = 0;
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i++){
scanf("%d", &p);
sum[i] = sum[i - 1] +p; //求前缀和
while (e >= s && sum[q[e]] >= sum[i]) e--; //构建递减的单调队列
q[++e] = i;
if (q[s] < i - m) s++; //满足区间长度不大于 m
maxn = max(maxn, sum[i] - sum[q[s]]);
}
cout << maxn << "\n";
return 0;
}