- 分治策略
分治策略是一种解决问题的思路:
将问题分为若干更小规模的部分
通过解决每一个小规模问题,并将结果汇总得到原问题的解。
PS:递归问题则体现了分治策略。
- 优化问题和贪心策略
1.优化问题例子:找零兑换问题(递归解法)
让自动售货机每次找零给顾客最少数量硬币。
贪心策略解决:我们每次都试图解决问题尽量大的一部分对应到兑换硬币问题,就是每次一最多数量的最大面额值硬币来迅速减少找零面值。但这并不是最优解。虽然尽量保证了每次找的是最优的,但组合起来不一定是最优解,只是接近最优解。
可采用递归解法来解决:
代码:
1 def recDC(coniValueList, change, knownResults): 2 ''' 3 :param coniValueList: 硬币面额数组 4 :param change: 需要找的钱 5 :param knownResults: 最优解的表 6 :return: 最优查找次数 7 ''' 8 minCoins = change 9 if change in coniValueList:#递归基本结束条件 10 knownResults[change] =1 #记录最优解 11 elif knownResults[change] >0: 12 return knownResults[change] #查表成功,直接用最优解 13 else: 14 for i in [c for c in coniValueList if c <=change]: 15 numConins = 1 + recDC(coniValueList,change - i,knownResults) 16 17 if numConins < minCoins: 18 minCoins = numConins #最小的找零次数 19 #找到最优解,记录到表中 20 knownResults[change] = minCoins 21 return minCoins 22 memo = [0] *64 #记录中间结果的表 23 print(recDC([1,5,10,25],63,memo)) 24 print(memo)
2.优化问题例子:找零兑换问题(动态规划解法)
大问题的最优解包含更小问题的子优解。
代码:
1 def dpMakeChange(coinValueList, change, minCoins, coinsUsed): 2 for cents in range(1, change + 1): 3 coinCount = cents 4 newCoin = 1 5 for j in [c for c in coinValueList if c <= cents]: 6 if minCoins[cents -j] + 1 < coinCount: 7 coinCount = minCoins[cents - j] + 1 8 newCoin = j 9 minCoins[cents] = coinCount 10 coinsUsed[cents] = newCoin # 记录本步骤加的一个硬币 11 return minCoins[change] 12 def printCoins(coinsUsed, change): 13 coin = change 14 while coin > 0: 15 thisCoin = coinsUsed[coin] 16 print(thisCoin) 17 coin = coin - thisCoin 18 19 amnt = 63 20 clist = [1, 5, 10, 21, 25] 21 coinsUsed = [0] * (amnt + 1) 22 coinsCount = [0] * (amnt + 1) 23 print(dpMakeChange(clist, amnt,coinsCount,coinsUsed)) 24 printCoins(coinsUsed, amnt) 25 print(coinsUsed)
输出:
3 21 21 21 [0, 1, 1, 1, 1, 5, 1, 1, 1, 1, 10, 1, 1, 1, 1, 5, 1, 1, 1, 1, 10, 21, 1, 1, 1, 25, 1, 1, 1, 1, 5, 10, 1, 1, 1, 10, 1, 1, 1, 1, 5, 10, 21, 1, 1, 10, 21, 1, 1, 1, 25, 1, 10, 1, 1, 5, 10, 1, 1, 1, 10, 1, 10, 21] Process finished with exit code 0