CHOJ1201最大子序和
1201 最大子序和 0x10「基本数据结构」例题
描述
输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。
例如 1,-3,5,1,-2,3
当m=4时,S=5+1-2+3=7
当m=2或m=3时,S=5+1=6
输入格式
第一行两个数n,m(n,m<=300000)
第二行有n个数,要求在n个数找到最大子序和
输出格式
一个数,数出他们的最大子序和
样例输入
6 4 1 -3 5 1 -2 3
样例输出
7
求出前缀和数组sum[],枚举右端点,典型单调队列题。。。
#include<bits/stdc++.h> using namespace std; #define why 300005 int q[why],n,m,ans,sum[why]; inline int redn() { int ret=0,f=1; char ch=getchar(); while(!isdigit(ch)) { f=(ch!='-')?f:-f; ch=getchar(); } while(isdigit(ch)) { ret=ret*10+ch-'0'; ch=getchar(); } return f>0?ret:-ret; } int main() { int l=1,r=1,_1; q[1]=0; //初始化 n=redn(); m=redn(); for(int i=1;i<=n;++i) { _1=redn(); sum[i]=sum[i-1]+_1; } //读入 for(int i=1;i<=n;++i) { while(l<=r&&q[l]<i-m)++l;//删除"过期"队首 ans=max(ans,sum[i]-sum[q[l]]);//更新答案 while(l<=r&&sum[q[r]]>=sum[i])--r;//删除不优秀的决策:(sum[i]-sum[q[r]])都<0了,何必留着 q[++r]=i;//i也是个好决策,可以更新后面的,所以入队 } printf("%d",ans); return 0; }
Orchideus Is Being Adorable.QwQ