注解满满,来讨论一下吧。为什么不能写solve(i,(i+j)/2)呢?如果写了某些情况会"无法求解",但我写了j==i+1时退出。我还尝试了写solve(i,(i+j)/2-1)测试点而出错。学术讨论,为什么分治递归求右边最大子列和就必须前进一步呢?
#include<iostream>
#include<algorithm>
using namespace std;
int a[200010];
int x;
int solve(int i, int j)//求i到j的最大和
{
if(j==i+1)return max(a[j]+a[i],max(a[i],a[j]));
if (i == j)return a[j];//如果序列长度唯一就直接返回唯一元素a[i]
int left = solve(i, (i + j) / 2);//递归求左半部分的最大和
int right = solve((i + j) / 2 , j);//递归求右半部分最大和
int mid1 = -1e8, mid2 = -1e8, mid;//要初始化为负无穷大
int sum = 0, k;
for (k = (i + j) / 2 + 1; k <= j; k++)//记录从中间+1到右边的连续不间断序列最大和
{
sum += a[k];
if (sum > mid2)mid2 = sum;
}
sum = 0;
for (k = (i + j) / 2; k >= i; k--)//记录从中间到左边连续不间断序列最大和
{
sum += a[k];
if (sum > mid1)mid1 = sum;
}
mid = mid1 + mid2;//合并为跨越中间的序列的最大和
cout << "i:" << i << " j:" << j << " mid:" << mid << " left:" << left << " right:" << right << endl;
return max(mid, max(left, right));//i到j的最大和 等于 i到中间序列的最大和 中间到j序列的最大和 跨越中间序列的最大和 的最大和
}
int main()
{
int n;
cin >> n;
x = 1;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] >= 0)x = 0;
}
cout << solve(1, n);
return 0;
}