動態規劃--python

當前子狀態選和不選的問題,
從後面往前面推:

當前A狀態選:A以前的最佳狀態B+A狀態的值
當前A狀態不選:A-1狀態

代碼編寫:
狀態用函數編寫
用一個數據來存放每一個當前的最佳狀態(即函數)

你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。

例題:leetcode–198.打家劫舍
https://leetcode-cn.com/problems/house-robber/

示例 1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。

示例 2:
輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接着偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。

設當前狀態爲opt(i)
則在arr = [1,2,4,1,7,8,3]當中

對於opt(4)
選擇opt(4) :opt(2)+arr[i]
不選擇opt(4) : opt(3)
則最佳選擇爲 max( opt(2)+arr[i] , opt(3) )

opt(i)…opt(0)根據這樣的規則類推
需要注意的是,要找到遞歸的出口:

opt(0)= arr[0]
opt(1) = max(arr[0],arr[1])

可得通項爲:

opt = max(opt(i-2)+arr[i],opt(i-1)), i>1
    = max(arr[i]) i<0

代碼如下:

import numpy as np

#遞歸實現
arr = [1,2,4,1,7,8,3]
def dec_opt(arr,i):
   if i == 0:
       return arr[0]
   elif i == 1:
       return max(arr[0],arr[1])
   else:
       a = dec_opt(arr,i - 2) + arr[i]
       b = dec_opt(arr,i - 1)
       return max(a,b)
print(dec_opt(arr,6))

#非遞歸實現
def dp_opt(arr):
	opt = np.zeros(len(arr))#創建一個和arr[]一樣長且全爲0的數組
   	opt[0] = arr[0]
    opt[1] = max(arr[0],arr[1])
    for i in range(2,len(arr)):
    	a = opt[i-2] + arr[i]
        b = opt[i-1]
        opt[i] = max(a,b)
    return opt[len(arr) - 1]
    
print(dp_opt(arr))

結果:

15
15.0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章