最大子序和
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 }
以上是关于最大子序和的主要内容,如果未能解决你的问题,请参考以下文章