思路:
其实就是一个动态规划,如果我们要求一个结尾为第 $ i $ 个元素的最大子段和,那么我们就维护一个前 $ i-1 $ 前缀和中的最小前缀和,然后这样我们用当前的前缀和 $ sum_i -sum_{min} $ 就是我们要求的结尾为第 $ i $ 个元素的最大子段和。
如图:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
const long long INF = 99999999999999999;
int n;
int arr[N];
long long ans=-INF,min_sum=INF,sum[N];
int main(){
scanf("%d",&n);
for(register int i=1;i<=n;i++){
scanf("%d",&arr[i]);
sum[i]=(long long)sum[i-1]+arr[i];
}
for(register int i=1;i<=n;i++){
min_sum=min(min_sum,sum[i-1]);
ans=max(ans,sum[i]-min_sum);
}
printf("%lld\n",ans);
return 0;
}