對於動態規劃,一直感覺會了,但又不怎麼會,難點的題也做不到自己完成,今天再總結一下:
首先動態規劃到底是幹啥的?
現在想來,應該是用陣列記錄遞迴中的結果【第一次接觸動態規劃就是斐波那契了吧
然後動態規劃要做到每次選最佳方案【opt】
對一陣列,選擇不相鄰的數,使其相加所得和最大
計算opt(i):遞迴寫法:opt(0)=arr[0]
opt(1)=max(arr[0],arr[1])
之後的最佳方案:
選擇第i個,那麼opt(i)=opt(i-2)+arr[i]
不選擇第i個,opt(i)=opt(i-1)
注:通常前兩個值是特殊值,不過特殊情況特殊考慮
arr=[1
,2,4
,1,7
,8,3
]def
opt(arr,i)
:if i==0:
return arr[0]
elif i==1:
return
max(arr[0]
,arr[1]
)else
: a=opt(arr,i-2)
+arr[i]
b=opt(arr,i-1)
return
max(a,b)
動規寫法:
將中間結果存在陣列opt中
import numpy as np#建立陣列用的包
defdp_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
]
對一陣列,判斷是否有兩數相加為特定數12?
剪枝,從後往前選或不選遞迴實現:sub(arr[6],12),【i=6,s=12】表示arr[6]前相加可以為12就行,對於arr[6]選或者不選
選為:sub(arr[i-1],s-arr[i])------>sub(arr[5],9)
不選為:sub(arr[i-1],s)------>sub(arr[5],12)
這兩個有乙個滿足返回true
特殊值:
def
sub(arr,i,s)
:if s==0:
return
true
elif i==0:
return arr[0]
==s elif arr[i]
>s:
return sub(arr,i-
1,s)
else
: a=sub(arr,i-
1,s)
b=sub(arr,i-
1,s-arr[i]
)return a or b
動規實現:
用二維陣列儲存:[arr[i],s]
import numpy as np
defdp_sub
(arr,su)
:#二維陣列設計
sub=zeros(
(len
(arr)
,s+1
),dtype=
bool
)#含s=0
sub[:,
0]=true
#每一行第0列【s==0】為true
sub[0,
:]=false
#第0行除arr[0]==s外,都為false
sub[
0,arr[0]
]=true
for i in
range(1
,len
(arr)):
for s in
range(1
,su+1)
:if arr[i]
>s:
sub[i,s]
=sub[i-
1,s]
else
: a=sub[i-
1,s]
b=sub[i-
1,s-arr[i]
] sub[i,s]
=a or b
r,c=sub.shape#獲得行數、列數
return sub[r-
1,c-
1]
關鍵點:
找出口【特殊值】
分析選或不選的公式
借助舊問題回顧動態規劃
一切要從乙個問題說起,聽說那是一道簡單的動態規劃題,於是我在半夜試著寫寫,誰知道到了第二天也沒有寫出來,看著45 的ac率,我想自己的動態規劃已經忘得差不多了 呵呵,應該說沒有學好 原問題 hdu 1466 計算直線的交點數 經典dp 平面上有n條直線,且無三線共點,問這些直線能有多少種不同交點數。...
動態規劃 什麼是動態規劃?
先來看看 資訊學奧賽一本通第5版 是怎麼說的 動態規劃程式設計是對解最優化問題的一種途徑 一種方法,而不是一種特殊演算法。不像前面所述的那些搜尋或數值計算那樣,具有乙個標準的數學表示式和明確清晰的解題方法。動態規劃程式設計往往是針對一種最優化問題,由於各種問題的性質不同,確定最優解的條件也互不相同,...
mysql動態規劃 動態規劃
動態規劃 能夠動態規劃的問題具有以下特點 可分解成規模更小的子問題 子問題的結果可復用 關鍵是要理解狀態轉移方程的含義就好啦!數字三角形 問題描述 在數字三角形尋找從頂到底的路徑,使得路徑經過的數字之和最大。規定每一步只能往左下或右下走,求出最大路徑和。遞迴解法 include include us...