动态规划实例(三):硬币找零方案
来源:互联网 发布:淘宝上极有家什么意思 编辑:程序博客网 时间:2024/06/05 17:05
问题:假设有m种面值不同的硬币,个个面值存于数组S ={S1,S2,… Sm}中,现在用这些硬币来找钱,各种硬币的使用个数不限。 求对于给定的钱数N,我们最多有几种不同的找钱方式。硬币的顺序并不重要。
例如,对于N = 4,S = {1,2,3},有四种方案:{1,1,1,1},{1,1,2},{2,2},{1, 3}。所以输出应该是4。对于N = 10,S = {2,5, 3,6},有五种解决办法:{2,2,2,2,2},{2,2,3,3},{2,2,6 },{2,3,5}和{5,5}。所以输出应该是5。
1)最优子结构
要算总数的解决方案,我们可以把所有的一整套解决方案在两组 (其实这个方法在组合数学中经常用到,要么包含某个元素要么不包含,用于递推公式等等,)。
1)解决方案不包含 第m种硬币(或Sm)。
2)解决方案包含至少一个 第m种硬币。
让数(S [] , M, N)是该函数来计算解的数目,则它可以表示为计数的总和(S [], M-1, N)和计数(S [],M,N-Sm)。
因此,这个问题具有最优子结构性质的问题。
2) 重叠子问题
例如,对于N = 4,S = {1,2,3},有四种方案:{1,1,1,1},{1,1,2},{2,2},{1, 3}。所以输出应该是4。对于N = 10,S = {2,5, 3,6},有五种解决办法:{2,2,2,2,2},{2,2,3,3},{2,2,6 },{2,3,5}和{5,5}。所以输出应该是5。
1)最优子结构
要算总数的解决方案,我们可以把所有的一整套解决方案在两组 (其实这个方法在组合数学中经常用到,要么包含某个元素要么不包含,用于递推公式等等,)。
1)解决方案不包含 第m种硬币(或Sm)。
2)解决方案包含至少一个 第m种硬币。
让数(S [] , M, N)是该函数来计算解的数目,则它可以表示为计数的总和(S [], M-1, N)和计数(S [],M,N-Sm)。
因此,这个问题具有最优子结构性质的问题。
2) 重叠子问题
具体实例及实现代码如下所示:
/** * @Title: CoinChange.java * @Package dynamicprogramming * @Description: TODO * @author peidong * @date 2017-6-7 上午8:57:21 * @version V1.0 */package dynamicprogramming;/** * @ClassName: CoinChange * @Description: 硬币找零 * @date 2017-6-7 上午8:57:21 * */public class CoinChange { /** * * @Title: coinChangRecursion * @Description: 递归解决方案 * @param s 硬币集合 * @param m 硬币种类 * @param n 钱数额 * @return * @return int * @throws */ public static int coinChangRecursion(int[] s, int m, int n){ //边界条件判断 if(n == 0) return 1; if(n < 0) return 0; if(m <= 0) return 0; //递归 return coinChangRecursion(s, m - 1, n) + coinChangRecursion(s, m, n - s[m-1]); } /** * * @Title: coinChange * @Description: 动态规划 * @param s 硬币数组 * @param m 硬币种类 * @param n 钱总数 * @return * @return int * @throws */ public static int coinChange(int[] s, int m, int n){ int res1, res2; //初始化状态转移数组 int[][] tc = new int[n+1][m]; //初始化状态转移数组 for(int i = 0; i < m; i++){ tc[0][i] = 1; } for(int i = 1; i < n+1; i++){ for(int j = 0; j < m; j++){ //包含s[j]时的种类 res1 = (i-s[j] >= 0)? tc[i - s[j]][j]: 0; //不包含s[j]的方案 res2 = (j >= 1)?tc[i][j-1]:0; tc[i][j] = res1 + res2; } } return tc[n][m-1]; } /** * @Title: main * @Description: TODO * @param args * @return void * @throws */ public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = {1, 2, 3}; int m = arr.length; int n = 4; System.out.println("使用递归求解硬币找零方案数为:" + coinChangRecursion(arr, m, n) ); System.out.println("使用动态规划求解硬币找零方案数为:" + coinChange(arr, m, n)); }}
阅读全文
0 0
- 动态规划实例(三):硬币找零方案
- 硬币找零(动态规划)
- 动态规划实例(九):最小硬币找零数
- 硬币找零问题(动态规划)
- 硬币找零问题(动态规划求解)
- 硬币找零问题 - 动态规划
- 动态规划算法求解硬币找零问题(Java)
- 动态规划算法求解硬币找零问题(Java)
- 硬币找零-记忆化搜索(DP动态规划)
- JAVA动态规划(一)--最少硬币找零问题
- 动态规划算法求解硬币找零问题 (2)
- 动态规划算法求解硬币找零问题(1)
- 动态规划算法求解硬币找零问题(Java)
- 动态规划法求解硬币找零(Java)
- 最少硬币找零问题-动态规划
- 最少硬币找零问题-动态规划
- 算法练习 动态规划 硬币找零
- 动态规划入门之硬币找零问题
- 行为型模式之解析器模式实现
- vi设置 打开文件直接跳到文件关闭时光标的位置
- django 用户认证 user对象
- 移动端与PHP服务端接口通信流程设计(基础版)
- list_for_each_entry
- 动态规划实例(三):硬币找零方案
- “玲珑杯”线上赛 Round #15 咸鱼文章(栈)
- JBOSS加密链接数据库
- opencv直方图相关及应用
- (安卓APP)关于简单的新手指导页的图片滑动和点击事件跳转
- C算法实现:将字符串中的数字返回为整型数
- Linux创建和删除用户
- 九度 题目1349:数字在排序数组中出现的次数
- html的简介