给出一个长度为\(n\)的序列\(a\),选出其中连续且非空的一段使得这段和最大。
给定一段数组\(A[low..high]\), 它的最大子数组所处的位置有三种情况:
#pragma warning(disable:4996) #include<iostream> #include<cstdio> #include<climits> #include<cfloat> using namespace std; typedef long long ll; const int maxn = 2e5 + 5; int n; ll a[maxn]; ll findCrossMax(int low, int mid, int high) { ll leftSum = LONG_MIN; ll sum = 0; for (int i = mid; i >= low; i--) { sum += a[i]; if (sum > leftSum) { leftSum = sum; } } ll rightSum = LONG_MIN; sum = 0; for (int i = mid + 1; i <= high; i++) { sum += a[i]; if (sum > rightSum) { rightSum = sum; } } return leftSum + rightSum; } ll findMax(int low, int high) { if (low == high) { return a[low]; } else { int mid = (low + high) / 2; ll leftResult = findMax(low, mid); ll rightResult = findMax(mid + 1, high); ll crossResult = findCrossMax(low, mid, high); return max(leftResult,max( crossResult, rightResult)); } } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } ll ans = findMax(1, n); printf("%lld", ans); return 0; }