一、暴力O(n^2)

二、分治O(nlogn)

从中间分开,分别比较分割线左、分割线右、包含分割线的三个区间。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, a[1000010];
int maxx(int l, int r) {
    int mid = (l + r) / 2;
    if(l == r) return a[l];
    int ans = max(maxx(l, mid), maxx(mid + 1, r));
    int ll = 0, rr = 0, tmp = 0;
    for(int i = mid + 1; i <= r; i ++) {
        tmp += a[i];
        ll = max(ll, tmp);
    }
    tmp = 0;
    for(int i = mid; i >= l; i --) {
        tmp += a[i];
        rr = max(rr, tmp);
    }
    ans = max(ans, ll + rr);
    return ans;
}
signed main() {
    scanf("%lld", &n);
    for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
    int num = maxx(1, n);
    cout << num << endl;
    return 0;
}

三、贪心O(n)

先求前缀和,答案在s[j] - s[i - 1]的遍历中出现
固定s[j]后找s[i - 1]的最小值。可以提前处理前缀和最小值

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, a[1000010], maxx[1000010], s[1000010];
signed main() {
    scanf("%lld", &n);
    memset(maxx, 0, sizeof maxx);
    for(int i = 1; i <= n; i ++) {
        scanf("%lld", &a[i]);
        s[i] = s[i - 1] + a[i];
    }
    for(int i = 1; i <= n; i ++) {
        maxx[i] = min(maxx[i - 1], s[i]);
    }
    int ans = 0;
    for(int i = 1; i <= n; i ++) {
        ans = max(ans, s[i] - maxx[i]);
    }
    cout << ans << endl;
    return 0;
}

四、动态规划O(n)

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, ans, a[1000010], f[1000010];
signed main() {
    scanf("%lld", &n);
    for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);
    for(int i = 1; i <= n; i ++) {
        f[i] = max(a[i], f[i - 1] + a[i]);
        ans = max(ans, f[i]);
    }
    cout << ans << endl;
}