题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050
本题的最大子段和分为两种情况:
(1)正常情况下的最大子段和
(2)首尾元素相接情况下的最大子段和。导致第二种情况的原因是数组中存在一段负数和,且其绝对值很大。这样我们便可以求解出这段负数和,然后用总的和减去这段负数和,剩下的那些元素和即为我们第二种情况下的最大子段和。
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 50010;
int arr[maxn];
int n;
ll max(ll a, ll b) {
return a > b ? a : b;
}
ll solve() {
ll ans = 0;
ll tmp = 0;
for(int i = 0; i < n; ++i) {
if(tmp <= 0) {
tmp = arr[i];
} else {
tmp += arr[i];
}
ans = max(ans, tmp);
}
return ans;
}
int main() {
//freopen("aa.in", "r", stdin);
ll ans = 0, ans1, ans2;
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
ans += arr[i];
}
ans1 = solve();
for(int i = 0; i < n; ++i) {
arr[i] = -arr[i];
}
ans2 = solve();
cout << max(ans1, ans + ans2) << endl;
return 0;
}