给定不同面额的硬币 coins ,每个值都代表一个面值的货币,每种面值都可以使用任意张,再给定一个总金额 amount,求换钱有多少种方法。
例如:
coins=[3, 5, 1], 总额amount = 11
组成的方法有5+5+1=11,3+3+5=11,3+3+1+1+1+1+1=11,3+3+3+1+1=11,
3+5+1+1+1=11,5+1+1+1+1+1+1=11,3+1+1+1+1+1+1+1+1=11,
1+1+1+1+1+1+1+1+1+1+1=11共8种。
a:要求空间的复杂度为O(M*N),时间复杂度O(M*N)
3:解答
1:前几天我们通过动态规划解决了用最少的硬币兑换零钱的问题,那么这个题目是不是也可以和上次那个那样,通过动态规划来实现呢?
2:首先关于动态规划的定义,可以查看相关的文章。
3:我们来举一个例子,首先声明一个dp[amount+1][n]的数组
假如只有一枚3元硬币
组成0元金额的方法有一种,那就是所有的硬币都不用,所以返回1。
组成1元金额的方法没有,所以返回0种。
组成2元金额的方法没有,所以返回0种。
组成3元金额的方法有1种,所以返回1种。
组成4元,5元金额的方法没有,所以返回0种。
组成6元金额的方法有1种,所以返回1种
组成7元,8元金额的方法没有,所以返回0种。
组成9元金额的方法有1种,所以返回1种
组成10元,11元金额的方法没有,所以返回0种。
以次类推,我们可以得到如下的结果
金额 0 1 2 3 4 5 6 7 8 9 10 11
====================================
3元 1 0 0 1 0 0 1 0 0 1 0 0
那如果用2张硬币3元和5元会怎么样呢?
金额 0 1 2 3 4 5 6 7 8 9 10 11
====================================
3元 1 0 0 1 0 0 1 0 0 1 0 0
5元 1 0 0 1 0 1 1 0 1 1 1 0
为什么这么写?同理我们可以分析一下
组成0元金额的方法也只有一种,那就是所有的硬币都不用,所以返回1。
组成1元金额的方法同样没有,所以返回0种。
组成2元金额的方法同样没有,所以返回0种。
组成3元金额的方法有1种,那就是使用上面的3元硬币,所以返回1种。
组成4元金额的方法没有,所以返回0种。
组成5元金额的方法有1种,所以返回1种。
组成6元金额的方法有1种,那就是使用上面的3元硬币,所以返回1种。
组成7元金额的方法没有,所以返回0种。
组成8元金额的方法有1种,那就是一个3元硬币和一个5元硬币,所以返回1种。
组成9元金额的方法有1种,使用上面的3元硬币,所以返回1种
组成10元金额的方法有1种,所以返回1种
组成11元金额的方法没有,所以返回0种。
当用3种硬币的时候,我们再次分析一下。
金额 0 1 2 3 4 5 6 7 8 9 10 11
====================================
3元 1 0 0 1 0 0 1 0 0 1 0 0
5元 1 0 0 1 0 1 1 0 1 1 1 0
1元 1 1 1 2 3 4 5 5 6 7 8 8
为什么一下子多这么多种方式呢?
组成0元金额的方法也只有一种,那就是所有的硬币都不用,所以返回1。
组成1元金额的方法有一种,就是使用1元硬币,所以返回1种。
组成2元金额的方法有一种,所以返回1种。
组成3元金额的方法有2种,那就是使用上面的3元硬币或者是3个一元的硬币,所以返回2种。
以此类推,可以得到结果。
示例代码请参看这里
https://github.com/1260380285/suanfa/blob/yuanbing/src/com/Corns.java
有些人可能对这一块有问题?
说明如下:
a)dp[i][j]=dp[i-1][j]是因为我们可以使用只有上面(i-1)硬币的情况
b)下面这个的意思是去掉当前的金额,剩余的金额还有几种组成方式
最后,如果好的话,记得留赞哦...
如果你觉得这篇文章有用,记得分享到朋友圈,关注下面的公众号,大家一起进步哦~
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章或有问题,欢迎留言和投稿~
如果你喜欢,请留下你的赞哦