動態規劃系列之二最大和子陣列

2022-01-12 14:52:46 字數 3304 閱讀 5623

給定乙個整數陣列 nums ,找到乙個具有最大和的子陣列(子陣列最少包含乙個元素),返回其最大和

輸入:[-2,-1,-3,4,-1,2,1,-5]

輸出: 6

解釋: 連續子陣列[4,-1,2,1]的和最大,為 6。

使用動態方程解題就需要題目符合動態方程解法,動態方程的兩個思路:

將大的問題拆解成小一點問題,小問題和大問題的解決思路是類似的

小問題之間的關係能完成大問題的最優解

求陣列arr中最大和的子陣列,建立乙個子陣列和的列表dp。其中dp[i]代表著以第i-1個元素結尾的陣列的最大和。

一般情況下,我們可以用dp[i]代表以第 i 個元素結尾的子陣列的最值,而遞推關係就是考慮和dp[i-1]之間的關係

dp[i]代表這以第i-1個元素結尾的子陣列的最大和,所以dp[0]就是邊界值。當陣列只有乙個元素時,該元素就是陣列的最大和

狀態轉移方程是最難寫的,但是我們要迎難而上。下面分析一下該狀態如何轉移。

這裡用dp[i]代表以第 i 個元素結尾的子陣列的最大和,則max(dp[i])就是要求的最終結果,那麼關鍵是如何寫出遞推關係式。

轉化後模型:

求i=7結尾的最大和。求i=7時,要知道前面的前乙個dp[7-1]的值。比較 dp[6] + nums[7] 和 nums[7] 的大小,大的那乙個就是dp[7]的值,也就是以 第7個元素結尾的子陣列的最大值。

這裡求8個元素的最大和的子陣列,這個大問題可以拆解成小問題,即求8個元素的最大和的子陣列,繼續拆解可以為求7個元素的最大和的子陣列,一直到求1個元素的最大和子陣列。

-2,-1,-3,4,-1,2,1,-5

-2,-1,-3,4,-1,2,1

-2,-1,-3,4,-1,2

-2,-1,-3,4,-1

-2,-1,-3,4

-2,-1,-3

-2,-1

-2

小問題之間的聯絡,可以完成大問題的最優解。

-2 最大和就是-2

-2,-1 以-1結尾的最大和為-1,因為前i-1個元素+i元素的最大值為負數,所以最大值為當前-1

-2,-1,-3 以-3結尾的最大和為-3,前2個元素+i元素的最大值為-3,相比較當前值-3,最大值就是-3

-2,-1,-3,4 以4結尾的最大和為4,前3個元素的最大和-3為負數,但沒第4個元素,所以最大的和為4

-2,-1,-3,4,-1 以-1結尾的最大和為3,前4個元素的最大和為4,所以加上當前值能變大,最大和為3

-2,-1,-3,4,-1,2 以2結尾的最大和為5,前5個元素的最大和為3,所以加上當前值能變大,最大和為5

-2,-1,-3,4,-1,2,1 以1結尾的最大和為1,前6個元素的最大和為5,加上當前值為6,

-2,-1,-3,4,-1,2,1,-5 以-5結尾的最大和1,前7個元素的最大和為1,大於0,所以加上當前元素能變大,最大和為1

統計出所有以第i個元素結尾的最大和為

-2-1-34

-121-5

-2-1-34

3561

可以看出當以1結尾時,可以獲得最大和的子陣列,值為6

明顯的,因為我們考慮的子陣列以nums[i]結尾,那麼該陣列一定是包含nums[i]這個元素的,因此需要考慮兩種情況:即nums[i]單獨成為一段還是與前面的dp[i-1]一起構成子陣列,因此,可以得到如下的遞推關係式:

dp[i]=max(dp[i-1]+nums[i],nums[i])
或者說:

dp[i-1]代表著前i-1個元素組成的子陣列的最大和,那麼加上第i個元素時就有兩種情況:

第i個元素 大於dp[i-1]+arr[i],那麼前i個元素的最大值為第i個元素的值

第i個元素 小於dp[i-1]+arr[i],那麼前i個元素的最大值為前i-1個元素的值 + 第i個元素

dp[i] = max
input_list = [-2,-1,-3,4,-1,2,1,-5]

length = len(input_list)

dp = [0] * length

# 邊界值,如果只有乙個元素,則第乙個元素的最大值就是自身

dp[0] = input_list[0]

for i in range(1,len(input_list)):

# if dp[i-1] + input_list[i] > input_list[i] ---> dp[i-1] > 0。或許前一種寫法更容易理解

if dp[i-1] > 0:

# 如果前i-1個元素的最大值大於0,那麼加上當前就能使得以當前值為結尾的最大和變大

dp[i] = dp[i-1] + input_list[i]

else:

# 如果前i-1個元素的最大值小於0,那麼加上當前就能使得以當前值為結尾的最大和變小。以當前值為結尾的最大和就是自身組成的陣列

dp[i] = input_list[i]

print(dp)

print(max(dp))

又可以寫成:

input_list = [-2,1,-3,4,-1,2,1,-5,4]

length = len(input_list)

# 構建乙個dp陣列,用來儲存以第i個元素為結尾的最大子陣列之和

dp = [0] * length

# 邊界值,如果只有乙個元素,則第乙個元素的最大值就是自身

dp[0] = input_list[0]

for i in range(1,length):

# 迴圈陣列,比較前i-1個陣列最大值+自身 和自身的大小。

# 如果大則表明前i-1個陣列是正數,則可以繼續加上第i個

# 如果小則表明前i-1個陣列是負數,那麼相加肯定更小,所以以自身為新起點繼續往下走

dp[i] = max(dp[i-1]+input_list[i],input_list[i])

print(max(dp))

最長連續子序的解法精華在於 維護了乙個dp陣列,該陣列中的每乙個元素都代表著前i-1個元素能夠組成的最大值,只需要比較前i-1個元素+第i個元素的值與第i個元素的值的大小,就能得到第前i個元素能夠組成的子陣列的最大值。

最大和子陣列 動態規劃

題目 題意 給出乙個陣列,要求乙個子陣列,使得子陣列中所有元素之和最大,輸出最大值以及子陣列的首尾元素。思路 設d i 為以第i個元素結尾即num i 元素結尾的子陣列元素最大和 d i max 設p i 為以第i個元素結尾的子陣列的首元素的下標 當d i d i 1 num i 時,p i p i...

動態規劃 連續子陣列的最大和

使用動態規劃 f i 以array i 為末尾元素的子陣列的和的最大值,子陣列的元素的相對位置不變 f i max f i 1 array i array i res 所有子陣列的和的最大值 res max res,f i 如陣列 6,3,2,7,15,1,2,2 初始狀態 f 0 6 res 6 ...

動態規劃搞最大和連續子陣列

給定乙個整數陣列 nums 找到乙個具有最大和的連續子陣列 子陣列最少包含乙個元素 返回其最大和。示例 輸入 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。剛看到這個題時,作為小白第一反應就是找到每乙個子陣列的和比較,那樣的話,就是三個for迴圈,...