給定乙個整數陣列 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迴圈,...