2 条题解
-
1938936 LV 7 MOD @ 2019-08-19 17:36:47
维护前缀和的最小值,然后枚举区间右端点
因为对于端点r,只需求S[r]-S[l-1]的最大值
故维护S(i) (i<r)的最小值即可得解
算法复杂度O(n)#include<iostream> #include<algorithm> using namespace std; int a[200001],s[200001],n; int main(){ int i; int mins=0,ans=0; s[0]=0; cin>>n; for(i=1;i<=n;i++){ cin>>a[i]; s[i]=s[i-1]+a[i]; } for(i=1;i<=n;i++){ ans=max(ans,s[i]-mins);//记录答案 mins=min(mins,s[i]);//维护左侧前缀和序列的最小值 } cout<<ans; }
-
02019-08-19 18:18:21@
30分/60分解法
30分直接求所有正数的和
60分,枚举区间,维护前缀和,剪枝排除区间端点为负数的情况即可#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int a[200001],s[200001],n; int main(){ register int i,j,ans=0; ios::sync_with_stdio(false); cin>>n; s[0]=0; for(i=1;i<=n;i++){ cin>>a[i]; s[i]=s[i-1]+a[i]; } bool flag=true; for(i=1;i<n;i++){//检测是否为单调递增 if(a[i+1]<a[i]){ flag=false; break; } } if(flag){//30分解法 for(i=1;i<=n;i++) if(a[i]>0) ans+=a[i]; } else{//60分解法 for(i=1;i<=n;i++){ if(a[i]<0) continue; //区间端点不能为负数 for(j=i;j<=n;j++){ ans=max(ans,s[j]-s[i-1]); } } } cout<<ans; }
- 1
信息
- ID
- 1000
- 难度
- 3
- 分类
- (无)
- 标签
- (无)
- 递交数
- 57
- 已通过
- 3
- 通过率
- 5%
- 上传者