最大子序和

Posted hhyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大子序和相关的知识,希望对你有一定的参考价值。

# 题意
长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大

# 题解
区间和问题,转化为两个前缀和相减的形式进行求解。
枚举右端点
贪心法求解,只需要对下标和前缀应用单调队列,在队列中下标位置递增,前缀和s也递增,
假如右端点r固定,找到一个左端点ll,要求j∈[i−m,i−1]
s[j]要尽量的小,为了使得区间和最大
j的取值,是一个区间,我们只要这个区间的最值。
区间最值,就可以通过单调队列处理。
我们发现如果说有一个位置k,k<j<i.而且sum[k]≥sum[j]
那么sum[i]−sum[k] <= sum[i]−sum[j],也就是说我们的 j 更靠近 i ,不易超过限制m,并且答案更优,那么k是没有用了。

所以每次更新的时候先把越界的队头去除,剩下的显然就是最优解
队列中存的是下标,而且值也是单调上升的,如果值比当前右端点大显然后面不会用到
所以一直累加即可 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=3e5+10;
 4 int q[N],h=1,t=1;
 5 int a[N],s[N];
 6 int n,m;
 7 int main(){
 8    cin>>n>>m;
 9    for(int i=1;i<=n;i++)
10    {
11       cin>>a[i];
12       s[i]=s[i-1]+a[i];
13    }
14    int ans=INT_MIN;
15    q[1]=0;
16    for(int i = 1;i<=n;i++)
17    {
18       while(h<=t && q[h] < i - m + 1) h++;
19       ans=max(ans,s[i] - s[q[h]]);
20 
21       while(h<=t && s[i] <= s[q[t]])
22          t--;
23 
24       q[++t]=i;
25    }
26    cout<<ans;
27 }

 

以上是关于最大子序和的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode53. 最大子序和

53.最大子序和

贪心——力扣53.最大子序和&&力扣122.买卖股票的最佳时机Ⅱ

C++ LeeCode 最大子序和

C++ LeeCode 最大子序和

TYVJ1305 最大子序和