_Ritchie

最大字段和

问题描述

给定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。


算法思想

算法一:穷举法

对序列中的所有子段进行遍历求和,通过比较不同子段的和,得到最大的子段和。

算法二:分治法

对于序列{a[i] | i = 1,2,3,…,n},取序列中心为分割点,将序列拆分为left:{a[i] | i = 1,2,…,n/2}和right:{a[i] | i = n/2+1,n/2+2,…,n}。这样最大的子序列将会有三种情况:(1)最大的子序列在left:{a[i] | i = 1,2,…,n/2}中;(2)最大的子序列在right:{a[i] | i = n/2+1,n/2+2,…,n}中;(3)最大的子序列一半在left,一半在right,也就是最大子序列中最少包含元素a[n/2]和a[n/2+1]。
对于这三种情况,只需要分别求解不同情况下的最大子段和,然后三者中最大的值既是整个序列的最大子段和。

算法三:动态规划

运用动态规划解决这个问题,关键的一步就是需要找到状态转移方程。对于序列{a[i] | i = 1,2,3,…,n},maxSum(m) = max{a[1]+a[2]+…+a[m]},即子字段{a[i] | i = 1,2,3,…,m}的最大字段和。由maxSum(m)到maxSum(m+1)的状态转移方程如下:
(1) 如果maxSum(m)>=0,maxSum(m+1)=maxSum(m)+a[m+1]
(2) 如果maxSum(m) < 0,maxSum(m+1)=a[m+1]
对于a[m+1]<0时,得到的maxSum(m+1) < maxSum(m)。所以,需要设置一个变量存储当前的最大字段值。上述的状态转移方程只是一个用于遍历不同子段值的方法。


代码实现

穷举法

# 算法的时间复杂度是O(n^3)
max = 0
for i = 1 to n :
    for j = i to n :
        sum = 0
        for k = i to j :
            sum += a[k]
        if max < sum :
            max = sum

分治法

# 算法的时间复杂度是O(nlogn)
def maxSum(a[], left, right) :
    max = 0
    if left == right :
        if left > 0 :
            max = a[left]
        else :
            max = 0
    else :
        center = (left + right) / 2
        leftMax = maxSum(a, left, center)
        rightMax = maxSum(a, center+1, right)
        centerSumLeft = 0
        leftSum = 0;
        for i = center to left :
            leftSum += a[i]
            if leftSum > centerSumLeft :
                centerSumLeft = leftSum
        centerSumRight = 0
        rightSum = 0
        for j = center+1 to right :
            rightSum += a[j]
            if rightSum > centerSumRight :
                centerSumRight = rightSum
        centerMax = centerSumLeft + centerSumRight
        if leftMax > centerMax :
            max = leftMax
        else if centerMax > rightMax :
            max = centerMax
        else :
            max = rightMax
    return max

动态规划

# 算法的时间复杂度是O(n)
max = 0
sum = 0
for i = 1 to n :
    if sum >= 0 :
        sum += a[i]
    else :
        sum = a[i]
    if sum > max :
        max = sum

posted on 2015-05-21 14:28  _Ritchie  阅读(217)  评论(0编辑  收藏  举报

导航