动态规划
如果我们有面值为1元、3元和5元的硬币若干枚,如何用最少的硬币凑够11元?
用d(i)=j 表示凑够 i 元最少需要 j 个硬币,求解过程如下:
- 当 i=0,表示凑够0元最小需要0个硬币
d(0)=0
- 当 i=1,只有面值为1元的硬币可用,因此拿起一个面值为1的硬币,接下来只需要凑够0元即可
d(1)=d(1-1)+1=d(0)+1=0+1=1
- 当 i=2,仍然只有面值为1的硬币可用,于是拿起一个面值为1的硬币, 接下来只需要再凑够2-1=1元即可
d(2)=d(2-1)+1=d(1)+1=1+1=2
- 当 i=3,能用的硬币就有两种了:1元的和3元的。此时就有两种方案:
(1)如果拿了一个1元的硬币,目标就变为了:凑够3-1=2元需要的最少硬币数量
(2)如果拿了一个3元的硬币,目标就变成了:凑够3-3=0元需要的最少硬币数量
d(3)=d(3-1)+1=d(2)+1=2+1=3
d(3)=d(3-3)+1=d(0)+1=0+1=1
d(3)=min{d(3-1)+1, d(3-3)+1}=1
硬币找零
题目:
假设有n种面值不同的硬币,个个面值存于数组 T[1:n] 中,现在用这些硬币来找钱,各种硬币的使用个数不限。求对于给定的钱数N,最少可以由几枚硬币组成,并输出硬币序列。
分析:
这是一个典型的动态规划问题,我们可以从1开始记录下每个钱数所需的最小硬币枚数。
实现:
def coinChange(values, valuesCounts, money, coinsUsed):
'''
:param values: 硬币的面值
:param valuesCounts: 硬币对应的种类数
:param money: 给定钱数 N
:param coinsUsed: 对应于目前钱数 i 所使用的最少硬币数目
:return: 对于给定钱数 N, 最少可以由几枚硬币组成, 并输出硬币序列
'''
# 遍历出从 1 到 money 所有的可能钱数
for cents in