/**
* 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],
* 求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。
* 当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为:
* Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n
* 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,
* 最大子段和为20。
*/
var a = [-2, 11, -4, 13, -5, -2];
console.log(maxsub(a));
// 分治法
function maxsub(a) {
function _maxsub(a, left, right) {
var sum, left_sum, right_sum;
var left_max, right_max;
var i, center = Math.floor((left+right)/2);
if (left === right) {
return a[left] > 0 ? a[left] : 0;
}
left_sum = _maxsub(a, left, center);
right_sum = _maxsub(a, center+1, right);
sum = 0;
left_max = 0;
for (i = center; i >= left; i--) {
sum += a[i];
if (sum > left_max) {
left_max = sum;
}
}
sum = 0;
right_max = 0;
for (i = center + 1; i <= right; i++) {
sum += a[i];
if (sum > right_max) {
right_max = sum;
}
}
sum = right_max + left_max;
if (sum < left_sum) {
sum = left_sum;
}
if (sum < right_sum) {
sum = right_sum;
}
return sum;
}
return _maxsub(a, 0, a.length-1);
}
// 动态规划法
function maxsub(a) {
var max, n = a.length, i, b = new Array(n);
max = b[0] = a[0];
for (i = 1; i < n; i++) {
b[i] = b[i-1]>0 ? b[i-1]+a[i] : a[i];
if (b[i]>max) {
max = b[i];
}
}
return max;
}
最优解:
function maxsub(a) {
var thisSum, maxSum;
thisSum = maxSum = 0;
for (var j = 0; j < a.length; j++) {
thisSum += a[j];
if (thisSum > maxSum) {
maxSum = thisSum;
} else if (thisSum < 0) {
thisSum = 0;
}
}
return maxSum;
}