题意
给你一个长度为 n的整数序列 {A1,A2,⋯,An}{A1,A2,⋯,An},要求从中找出一段连续的长度不超过 m的非空子序列,使得这个序列的和最大。
思路
因为是求子段和,所以存在多种情况比较的情况,马上思考到的就是前缀和方法,这样在求某段和的时候能够有效减少时间复杂度,接下来就是对算法的优化了。这里用到单调队列(但是队内都要满足一个条件,队头一定是小于a数组第i个数值)在每一个数的循环的结尾保存该次循环在在前缀和里的差值。
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5+10;
long long a[maxn];
int q[maxn];
int main()
{
int n, k;cin >> n >> k;
for(int i = 1;i <= n;++i)
{
cin >> a[i];
a[i] += a[i-1];
}//构建前缀和数组
long long ans = -maxn;
int head=1,tail=1;
q[head] = 0;
for(int i = 1;i <= n;++i)
{
while(head <= tail && i - q[head] > k) head++;
if(a[q[head]] >= a[i])
{
while(head <= tail && a[q[head]]