演算法初識_動態規劃
最近做題用到動態規劃,去B站看到燈哥視訊,從實戰出發講解很是清楚,連線地址第一講,第二講,本文結合相關理論和視訊學習總結如下。
1.動態規劃是什麼
是求解最優解的一個策略,將大問題分成同質的小問題,可以是求得最大,最小,或判斷是否有解……。
2.分類
一般可分為線性動規,區域動規,樹形動規,揹包動規四類。
3.為什麼動態規劃是具有重疊子結構的問題
從斐波那契數列和一個動態規劃問題的例子談起。
從圖中可以看出,動態規劃也可以用遞迴來分析,存在重疊子問題,但是動態規劃不推崇使用,可以避免重複計算。
4. 用例項重新認識動態規劃
(1)給出一組數1,2,4,1,7,8,3,選出一組資料,要求其和最大,且被選資料不能相鄰
分析:假設有陣列arr=[1,2,4,1,7,8,3]
0 | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 2 | 4 | 1 | 7 | 8 | 3 |
動態規劃問題都可以理解為選或不選問題。
1)假設對arr[6]進行選取判斷,則會有兩種結果
選:maxsum += arr[6]+opt[6-2] #opt表示選取的最優解
不選:maxsum += arr[6-1]
……
2)按照上述對第i個元素進行操作時結果如下:
選:maxsum += arr[i]+opt[i-2] #opt表示選取的最優解
不選:maxsum += arr[i-1]
3)結束條件:
假設只有一個元素,則maxsum = arr[0]
假設包含兩個元素,則maxsum = max(arr[0],arr[1])
4)程式碼如下:
import numpy as np arr = [1,2,4,1,7,8,3] def rec_opt(arr,i): #遞迴解法 if i == 0: return arr[0] elif i==1: return max(arr[0],arr[1]) else: A = rec_opt(arr,i-2)+arr[i] B = rec_opt(arr,i-1) return max(A,B) def dp_opt(arr): #非遞迴解法 opt = np.zeros(len(arr)) 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] dp_opt(arr)
(2)一組資料3,34,4,12,5,2,問是否可以通過若干個數相加獲得9
1)假設對arr[6]進行選取判斷,則會有兩種結果選:maxsum += arr[6]+opt[6-2] #opt表示選取的最優解
不選:maxsum += arr[6-1]
……
2)按照上述對第i個元素進行操作時結果如下:
選:maxsum += arr[i]+opt[i-2] #opt表示選取的最優解
不選:maxsum += arr[i-1]
3)結束條件:
假設只有一個元素,則maxsum = arr[0]
假設包含兩個元素,則maxsum = max(arr[0],arr[1])