校招筆試面試前,大家一般都會先去牛客網上刷刷題,《劍指offer》,《leetcode》走起來,然後初次入手,發現很多不會,不會到什麼程度呢,連個想法都沒有,於是就去討論區看答案,然後java大神,c++大神會給出花式解答,他們喜歡在答案前加一句,簡單的dp算法,遞歸就可以解決,巴拉巴拉。說的還是很詳細的,然而代碼並不能看懂,畢竟
人生苦短,我用python
下面就先給大家舉一些詳細的例子來說說如何解決動態規劃問題
首先,你要知道什麼才能算動態規劃問題,這裏,推薦《算法圖解》這本書,是基於python寫的一本算法講解書,內容非常簡單,沒未接觸過算法的人也能看懂,我先直接引用這裏的講法:
動態規劃就是要將問題細分爲小問題,然後再着手解決這些小問題。
例1:(題目來源於牛客網)
題目描述
輸入描述:
輸入爲一個數字N,即需要拼湊的面額
輸出描述:
輸出也是一個數字,爲組成N的組合個數。
這可以視爲一個動態迴歸問題解決,首先我們可以畫一個dp表格
dp表的列數字表示要拼成的面額,行表示可以用哪幾種面額的拼,比如說dp的一元行,5元列表示只用一元錢拼成5元錢只有一種方法,dp1元,5元行、6元列表示用幣值1元和5元拼成6元的方法有兩種,明顯dp[1,:]=1,而若j>i,dp[i,j]=dp[i-1,j]+dp[i,j-i],例如dp[2,10]=dp[1,10]+dp[2,5], 這個表達式說明,用1元和5元的面額拼成10元的方法數=用1元拼成10元的方法數+用1元和5元拼成5元的方法數,因爲面額6-9元拼成方法都是一樣的,暫時沒有更小的面額可供選擇,這個公式便是這個算法的核心
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
1元 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
1元,5元 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 3 |
1,元,5元,10元 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 4 |
1,5,10,20元 | |||||||||||
,1,5,10,20,50元 | |||||||||||
,1,5,10,20,50,100元 |
代碼如下
money=[1,5,10,20,50,100]
n = int(input())
li=[]
for i in range(n+1):
li.append(0)
li[0]=1
for i in money:
for j in range(n+1):
if j>=i:
li[j]=li[j]+li[j-i]
print(li)
例2 來源於《劍指offer》題目描述
簡單來說就是求一個最大子串問題,也是一個典型的動態規劃問題
思路:設F(i)是以array[i]爲結束點的最大子向量(從0開始),比如說F(3)就是最後一個向量是7的最大子串,可知
F(i) = max(F(i-1)+array[i],array[i])
設res是所有字串中最大的那個,也就是我們最後要求的值
res = max(res,F(i))
代碼:
def FindGreatestSumOfSubArray(array):
f = array[0]
res = array[0]
for i in range(1,len(array)):
f = max(f+array[i],array[i])
res = max(res,f)
return res
這樣便求得最後的解,不懂的話可以自己手寫一下循環,多悟幾次,日後使用起來就很方便啦