動態規劃 最大m子段和

2021-10-02 13:01:39 字數 2342 閱讀 3513

在最大m子段和問題中,要求取m個互不相交子段,和為最大值。最大m子段和問題是最大子段和在子段個數上的推廣,最大子段和問題是m=1的特殊情況。

在這個問題中,我們使用乙個矩陣b[ i ][ j ],他表示的意義是在前 j 項中被分為 i 段的最大 i 子段和。

首先,既然是前 j 項需要分為 i 段,所以當 i == j 的時候,陣列中的每個數自為一段,此時的值就是前 j 項的和。所以對角線上的值就是前 j 項加起來。

剩下的情況如下圖:

若要確定藍色塊的值,則在黃色塊中尋找乙個最大值,與紅色塊比較,取大者加在自身上。

若是黃色塊,當前值則是乙個新的子段的開始。若是紅色塊,當前值是和前乙個值一起組合成乙個子段的。

若要找分為4段的值,則在第4行找最大值即可。

因為所有值是通過左上方或左方而來,所以為了節省時間和空間,可以將b矩陣按如下簡化:

**如下:

def

max_sum_3

(m, n, a)

:if n < m or m <1:

return

b =for i in

range(0

, m +1)

:)for j in

range(0

, n +1)

: b[i]0)

for i in

range(1

, m +1)

:for j in

range

(i, n - m + i)

:if j > i:

b[i]

[j]= b[i]

[j-1

]+ a[j]

for k in

range

(i -

1, j)

:if b[i]

[j]< b[i-1]

[k]+ a[j]

: b[i]

[j]= b[i-1]

[k]+ a[j]

else

: b[i]

[j]= b[i-1]

[j-1

]+ a[j]

sum=

0for j in

range

(m, n +1)

:ifsum< b[m]

[j]:

sum= b[m]

[j]return

sum

跟最大子段和問題類似,在最大子段和問題中,只用到了b[j]和b[j-1],因此只使用乙個b來節約空間。同樣地,在最大m子段和問題中,只使用了j行和j-1行,因此使用兩個陣列即可。

更改後的**如下:

def

max_sum_4

(m, n, a)

:if n < m or m <1:

return

b =c =

for i in

range(0

, n - m +1)

:0)0

)for i in

range(0

, m)

: b[0]

= c[0]

+ a[i]

for j in

range(1

, n - m +1)

: b[j]

= b[j -1]

+ a[i + j]

for k in

range(0

, j +1)

:if b[j]

< c[k]

+ a[i + j]

: b[j]

= c[k]

+ a[i + j]

for j in

range(0

, n - m +1)

: c[j]

= b[j]

sum=

0for i in

range(0

, n - m +1)

:ifsum< b[i]

:sum

= b[i]

return

sum

動態規劃 最大m子段和

繼最大子段和在空間上的推廣,那麼再來看看她在個數上的延伸。最大子段和就是最大m子段和問題在m 1時的特殊情況 類似最大欄位和中的b j 這裡假設b i,j 表示陣列a的前j項中i個子段和的最大值,且第i個子段含a j 其中b i,j 1 a j 表示第i個子段含a j 而 初始時b 0,j 0,0 ...

最小m子段和(動態規劃)

問題描述 給定n個整數組成的序列,現在要求將序列分割為m段,每段子序列中的數在原序列中連續排列。如何分割才能使這m段子序列的和的最大值達到最小?輸入格式 第一行給出n,m,表示有n個數分成m段,隨後一行給出n個數,以空格分隔 輸入樣例 9 39 8 7 6 5 4 3 2 1 輸出樣例 解釋 9 8...

最大m子段和

最大m子段和問題 給定由n個整數 可能為負 組成的序列a1 a2 a3.an,以及乙個正整數m,要求確定序列的m個不想交子段,使這m個子段的總和最大!設b i,j 表示陣列a的前j項中i個子段和的最大值,並且第i個子段包含a j 1 i m,i j n 則所求的最優值為maxb m,j m j n ...