最大连续和
题目链接:ybt金牌导航1-4-2
题目大意
有一个序列,要你找一个长度不大于 m 的连续子序列使得序列和最大。
思路
这道题我们先我们看到长度不大于 m,想到可能可以用单调队列的方法。
但是你会发现直接套并不可行,因为它是求区间和而不是区间极值。
那你考虑转化成区间极值,当你确定右端点的时候,你就要让你选的区间
a
a
a 的和最大,也就是说让如图的区间
b
b
b 的和最小。
那你会发现区间 b b b 其实是前缀,那就变成在这个数的前缀里面找最小,然后就变成了单调队列。
所以你就把他的前缀和弄出来然后搞单调队列就可以了。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n, m, a[200001], l, r, que[200001];
int s[200001], now, ans = -1e9;
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]), s[i] = s[i - 1] + a[i];//求前缀和
l = 1;
r = 1;
for (int i = 1; i <= n; i++) {//单调队列找固定区间长度的区间最小
while (l <= r && i - que[l] > m) l++;
ans = max(ans, s[i] - s[que[l]]);
while (l <= r && s[i] <= s[que[r]]) r--;
que[++r] = i;
}
printf("%d", ans);
return 0;
}