1.问题描述:
硬币问题是比较古老而又经典的问题,即给定需要凑的硬币,给定几种面值的硬币,问最少所需要的硬币个数凑成。
比如 给定15 硬币面值为1 ,5,11三个面值
即输入 15
输出为最少的硬币个数:3
2.算法分析:
其实硬币问题也可以算是贪心问题,比如给定面值为100 ,50,10,1的面值,我们给定
666,如果凑666的话,我们可以从大的凑,再从小的凑,比如
666 = 6 * 100 + 50 * 1 + 10 * 1 + 6 * 1 = (6 + 1 + 1 + 6) = 14
这样解即是最优解。
但是我们如果用这个贪心策略来解该问题的话,可能取不到想要的效果。
比如 15 = 11 * 1 + 1 * 4 = (1 + 4 = 5),但是这并不是最优的解,
比如15 = 5 * 3 = 3应该才是最优解。
所以,关于这个问题,其实对于数据规模大的时候我们采用贪心是没有错的,对于小规模数据我们使用DP来解,这是对于硬币问题最好的解决方式。
我们分析该怎么做呢。
其实我们不难发现我们每次考虑三种硬币即可,每次的选取应该是,
对于每个需要凑的硬币用dp数组来记录。dp[n]代表所需凑成n的最小硬币。
不难发现每个dp[n] 与 dp[n - 1],dp[n - 5],dp[n - 11]的关系:
dp[n] = min(dp[n - 1], dp[n - 5], dp[n - 11])