动态规划:最大子矩阵和问题

大家好,我是连人。本期我们讨论最大子段和的第一个推广问题:最大子矩阵和问题。

最大子段和问题:

首先先简单介绍一下最大子段和问题:在数组a中存放着n个整数,求i,j∈[0,n](i<j)使i和j区间内所有整数相加和最大。

如果a数组内全是负数,则最后结果记为0。

针对这个问题,我们设立一个变量b,b的规则是:

当b[j-1]>0时,b[j] = b[j-1] + a[j]
否则b[j] = a[j]

因此b[j]的动态规划递归式为b[j]=max{ b[j-1] + a[j] ,a[j] }

因为在判断b[j]取值时只需要b[j-1],为了节省空间,直接将数组的预算砍成一个变量b,这个变量的目的以通俗的话讲就是抛弃负数留下正数。

下面为代码:

def max_sum_1(n, a):
    sum = 0
    b = 0
    for i in range(0, n):
        if b > 0:
            b += a[i]
        else:
            b = a[i]
        if b > sum:
            sum = b
    return sum

最大子矩阵和问题

将最大字段和问题引申,给定一个矩阵,求一子矩阵的和,使该子矩阵中元素和是所有子矩阵元素和最大的一个。

对于这个问题,可以将“矩阵的和”通过叠放转化为最大子段和问题中的数组,然后将这个数组再通过最大子段和问题找出sum。

步骤如下图。
在这里插入图片描述
此时b数组值如图,根据max_sum_1可知7,3是最大字段和10,指代A2:A3矩阵,计入sum。

之后再次向下:
在这里插入图片描述
此时b数组值如图,最大子段4,-1,-1,4,和为6,指代A1:B4矩阵,但由于6<10,因此不计入sum,继续向下遍历。
在这里插入图片描述
此时b如图,最大子段7,-3,3,9,和为16,指代A1:C4,由于16>10,sum被取代为16,接着向下循环。

在这里插入图片描述
第二轮的循环从B行开始,然后重复上述循环。

下面是代码:

def max_sum_2(m, n, a):
    sum = 0
    for i in range(0, m):
        b = []
        for k in range(0, n):
            b.append(0)
        for j in range(i, m):
            for k in range(0, n):
                b[k] += a[j][k]
            max = max_sum_1(n, b)
            if max > sum:
                sum = max
    return sum

转载注明出处。

  • 29
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值