找零問題之動態規劃法求解Python

2021-10-24 00:24:46 字數 1688 閱讀 5179

遞迴是從後往前逐步判斷求解,17元有哪個和哪個組成,而哪個又由–和--組成,其實除了遞迴求解,也可以換種思路,從前往後逐步遞推。

從小到大都求出來最優解,逐步遞推。而大的最優解一定包含某個小的最優解(注意是某乙個,這個是不確定的,用反證法),如果不包含,那必定還有乙個解,這個解和最優解一定有乙個是最優的,無論哪個都把之前的前提能夠推翻。

比如,找零17元,面值有1,5,10,25四種金額。和遞迴一樣,只不過是從小到大逐步求解(可以看成是遞迴的非遞迴形式)。

先求出找零1元的最優解,即1張1元。然後是2元,2元是由1元的最優解組成2張2元的,以此類推,找零5元,此時5元的最優解即變成1張5元,5元則是由5元的最優解組成,然後是6元,1張1元和1張5元,6元是在5元的最優解的基礎上求出。

**那麼到底如何求解呢?和遞迴的思路一樣,還是上面的例子,已知有面值金額的種類,那麼,比如找零7元,因為目前可選的只有面值1元和5元找零,所以最優解一定是1元和找零6元的最優解,或者是5元和找零2元的最優解。**其實就是把當前能夠用面值金額直接找零的都算一遍,進行對比找出最小的。

為了儲存,用乙個列表儲存每個值的找零數量最小值,為了儲存找零方案,記錄當前找零所用到的面值,(找零子集不用記錄,比如找零7元,可以直接記錄5,此時就代表用一張面值為5元的紙幣,然後再直接用7-5=2,去查詢找零2元用到的面值即可)。

# 動態規劃解決找零問題

def dpmakechange(coinvaluelist, change, mincoins, coinsused):

dic = {}

for cents in range(1, change+1):

coincount = cents

newcoin = 1

for j in [c for c in coinvaluelist if c <= cents]:

if mincoins[cents - j] + 1 < coincount:

coincount = mincoins[cents - j] + 1

newcoin = j

mincoins[cents] = coincount

coinsused[cents] = newcoin

return mincoins[change]

def printcoins(coinsused, change):

coin = change

while coin > 0:

thiscoin = coinsused[coin]

print(thiscoin)

coin = coin - thiscoin

amnt = 63

clist = [1,5,10,21,25]

coinsused = [0] * (amnt + 1)

coincount = [0] * (amnt + 1)

print("****** change for", amnt, 'requires')

print(dpmakechange(clist, amnt, coincount, coinsused), 'coins')

print('they are:')

printcoins(coinsused, amnt)

print('the used list is as follows:')

print(coinsused)

動態規劃法解找零錢問題

目錄動態規劃法將待求解問題分解成若干個相互重疊的子問題,每個子問題對應決策過程的乙個階段,一般來說,子問題的重疊關係表現在對給定問題求解的遞推關係稱為動態規劃函式中,將子問題的解求解一次並填入表中,當需要再次求解此子問題時,可以通過查表獲得該子問題的解,從而避免了大量重複計算。具體的動態規劃法多種多...

動態規劃法求解RMQ

題目描述 思路分析 下面把sparse table演算法分成預處理和查詢兩部分來說明 以求最小值為例 預處理 預處理使用dp的思想,f i,j 表示 i,i 2 j 1 區間中的最小值,我們可以開闢乙個陣列專門來儲存f i,j 的值。例如,f 0,0 表示 0,0 之間的最小值,就是num 0 f ...

動態規劃法求解TSP問題 C

此文章借鑑於博文在此基礎上重新進行了分析總結。1 怎麼求頂點子集,即這些怎麼記錄?答 例如4個頂點,依次為 十進位制數0 1 2 3 4 5 6 7的二進位制分別為000 001 010 011 100 101 110 111。上述集合中的元素即為二進位制中的位數,例如集合,可用二進位制110 十進...