最大连续子段和,最大连续m段和。动态规划。

首先是最大连续子段和的问题,
题目描述:求一个数组arr=[-2,1,-3,4,-1,2,1,-5,4],的最大连续的子段的和。
题解:使用动态规划,定义辅助数组dpc记录以当前元素结尾的最大连续的子段和。即dpc[i]表示的是在arr列表中以arr[i]结尾的最大连续的子段和。那么显然dpc[i]有两种情况,一个是arr[i]加在了arr[i-1]之后,那么此时最大的连续子段和dpc[i] = dpc[i-1]+arr[i]另外一种就是arr[i]独自成一个子段
此时dpc[i] = arr[i],所以dpc[i]=max( dpc[i-1]+arr[i], arr[i]),这就是递推公式了。代码如下:

def dp_sum(arr):
    res = [0 for i in range(len(arr))]
    res[0] = arr[0]
    for i in range(1,len(arr)):
        res[i] = max(res[i-1]+arr[i],arr[i])
    return res
dp_sum(arr)

最后的结果就是dpc的最大值。
最大连续字段和还是比较简单好理解的,然后就是他的升级版,最大连续m段和。
题目描述:将一个数组arr=[-2,1,-3,4,-1,2,1,-5,4],分为m个连续的子段,求m段的最大和。
题解:利用二维的dp,dpc[i][j] 表示分为i段并以arr[j]结尾的i段最大的和。为了让第i行,就是分为第i段,我们将第0行用0填补。先思考下边界,首先按照上面的意思第一行就是上面求的最大连续子段和的结果,其次对于长度为i的列表alist我们将其分为i段,那么其最大和就是sum(alist),所以
dpc[i][i-1] = sum(arr[:i])
下面来讨论下递推公式,对于dpc[i][j] 可以从哪里来呢?坠在dpc[i][j-1]的前面,和前面的连在一起作为一段。即dpc[i][j][ = dpc[i][j-1]+arr[j],其次他可以单独成为一段,即从dpc[i-1]这一行过来,那么他的最大值就是max(dpc[i-1])+arr[j],最终的递推方程式:
dpc[i][j] = max(dpc[i][j-1]+arr[j],max(dpc[i-1]) + arr[j])
代码如下:

k = dp_sum(arr)
arr=[1,-2,3,4,-5,-6]
dpc = [[0]*6 for j in range(7)]
for i in range(2,7):
    dpc[i][i-1] = sum(arr[:i])
for j in range(len(dpc[0])):
    dpc[1][j] = kk[j]
for i in range(2,len(dpc)):
    for j in range(i,len(dpc[0])):
        max_value = -100
        for k in range(j):
            max_value = max(max_value,dpc[i-1][k])
        dpc[i][j] = max(dpc[i][j-1]+arr[j] ,max_value+arr[j])

猜你喜欢

转载自blog.csdn.net/qq_42232193/article/details/105489137