[动态规划] 找硬币问题
问题:
有3,5,7分钱的硬币,以及给定的数额N,求找开N所需的最小硬币数目。
扩展问题:
有(V1, V2, V3, ..., Vm)硬币面额,面额数目为m,以及给定的数额N,求找开N所需的最小硬币数目,或断定不能找开。
硬币找零是比较经典的动态规划问题,在某些面额组合的情况下,可以用贪心算法求解。《算法导论》中将硬币找零问题作为贪心算法的例子。在这里,随机选取三个素数作为面额。
对于某一数额N,若能被给定的面额找开,可以分为两种情况。
1、N恰好等于某一硬币的面额,这样找开N只需一枚硬币;
2、N需要多枚硬币才能找开。
现在主要分析第二种情况。当一枚硬币找不开时,则数额N一定可以被分为两个子数额N1,N2的找零问题,其中N1+N2=N,且要分别找到N1,N2的最优解。
定义f(N)为对数额N的找零最小硬币数,可以写出递归式。
f(N) = 1 N恰好为某一硬币面额
f(N) = min(i from 1 to N/2) ( f(i) + f(N-i) ) N不是硬币面额
可以利用动态规划求解。以23为例进行计算。
N | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
f(N) | -1 | -1 | 1 | -1 | 1 | 2 | 1 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 4 | 3 | 4 | 3 | 4 | 3 | 4 | 5 |
f(23) = 5
数额23在硬币面额为(3,5,7)的情况下可以找开,最少需要5枚硬币。