题目传送门
分别f[i][1/0]表示到第i位从前面或从后面子序列的最大和,最后枚举断点即可.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
long long f[1000001][2],a[1000001],ans = -80000000000000,_ans[1000001][2];
inline long long _max(long long s,int d) {
if(s > d) return s;
return d;
}
int main() {
scanf("%d",&n);
for(int i = 1;i <= n; i++) {
scanf("%lld",&a[i]);
f[i][1] = f[i][0] = _ans[i][1] = _ans[i][0] = -8000000000000000;
}
_ans[1][0] = f[1][0] = a[1];
for(int i = 2;i <= n; i++)
f[i][0] = _max(f[i-1][0],0) + a[i],_ans[i][0] = max(_ans[i+1][0],f[i][0]);
_ans[n][1] = f[n][1] = a[n];
for(int i = n - 1;i >= 1; i--)
f[i][1] = _max(f[i+1][1],0) + a[i],_ans[i][1] = max(_ans[i+1][1],f[i][1]);
for(int i = 2;i < n; i++)
ans = max(ans,_ans[i-1][0] + _ans[i+1][1]);
printf("%lld",ans);
return 0;
}