Ref: [Optimization] Dynamic programming【寻找子问题】html
Ref: [Optimization] Advanced Dynamic programming【优于recursion】缓存
显然,本篇是关于”动态规划"的部分。ui
要点:”个数“其实表明了“for循环”的层数。但“个数”不定,使用“递归”反而能解决这个问题,减小思路上的负担。 this
import time def recMC(coinValueList, change):
minCoins = change if change in coinValueList: return 1 else: for i in [c for c in coinValueList if c <= change]: # 遍历每个变量, 至关于多重循环。有意思的是,循环的深度是不肯定的; numCoins = 1 + recMC(coinValueList, change-i)
# 获得这个遍历分支的最终结果; if numCoins < minCoins: minCoins = numCoins
return minCoins start = time.time() print(recMC([1,5,10,25], 63)) end = time.time() print(end-start)
耗时:31秒。spa
要点:增长了”结果缓存“,效率极具增长。3d
代码中的 knownResults 记录了上图中节点(某个change时)的最优/最小的值,做为了记录。code
def recDC(coinValueList, change, knownResults):
minCoins = change if change in coinValueList: knownResults[change] = 1 # 一个硬币刚恰好 return 1 elif knownResults[change] > 0: return knownResults[change] else: for i in [c for c in coinValueList if c <= change]:
# numCoins = 1 + recDC(coinValueList, change-i, knownResults)
# 更新minCoins if numCoins < minCoins: minCoins = numCoins knownResults[change] = minCoins return minCoins
def main():
amnt = 2163 print(recDC([1,2,5,10,21,25], amnt, [0]*(amnt+1))) main()
耗时:0.01秒。htm
要点:不是从上到下的 (递归) 思惟,且容易栈溢出;而是从最小的状况入手,逐渐扩大。blog
def dpMakeChange(coinValueList, change, minCoins, coinsUsed): # 首先,考虑全部的 "状况",是从小到大考虑 for cents in range(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 @fn_timer def main(): amnt = 2163 clist = [1,2,5,10,21,25] coinsUsed = [0]*(amnt+1) coinsCount = [0]*(amnt+1) # print("Making change for", amnt, "requires") print(dpMakeChange(clist, amnt, coinsCount, coinsUsed), "coins") # print("They are:") # printCoins(coinsUsed,amnt) # print("The used list is as follows:") # print(coinsUsed) main()
耗时:0.003秒。递归
End.