DP7 两道换硬币的问题 Coin Change @geeksforgeeks
来源:互联网 发布:淘宝网名昵称大全女生 编辑:程序博客网 时间:2024/06/06 02:06
1 Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.
两种思路:
1)http://www.cs.ucf.edu/~dmarino/ucf/cop3530/lectures/COP3530DynProg02.doc
特别注意到换完的硬币是没有顺序的,所以要impose order
2)http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
http://www.cnblogs.com/python27/p/3303721.html
http://www.mathblog.dk/project-euler-31-combinations-english-currency-denominations/
考虑是否取最后一个硬币,转换为背包问题
package DP;import java.util.Arrays;/**Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter. */public class CoinChange1 {public static int MEM[] = new int[10001]; // Can support up to 10000 peso value public static void main(String[] args) { int coins[] = {1, 2, 3}; // Available coin denominations Arrays.sort(coins); int coinKinds = coins.length; int sum = 4; System.out.println(countRec_1st(coins, coinKinds, sum, coins[coins.length-1])); System.out.println(countRec_2nd(coins, coinKinds, sum)); System.out.println(countDP_1st(coins, coinKinds, sum)); System.out.println(countDP2D_2nd(coins, coinKinds, sum)); System.out.println(countDP1D_2nd(coins, coinKinds, sum)); } //====================================第一种思路 /* max 用来保持order,否则就会有重复,如(1,2),(2,1) */ public static int countRec_1st(int coins[], int coinKinds, int sum, int max){ if(sum < 0){ return 0; } if(sum == 0){ return 1; } int ways = 0; for(int i=0; i<coinKinds; i++){ if(max >= coins[i]){ ways += countRec_1st(coins, coinKinds, sum-coins[i], coins[i]); } } return ways; } // http://www.cnblogs.com/python27/p/3303721.html // dp[i][j] = sum(dp[i-1][j-k*coins[i-1]]) for k = 1,2,..., j/coins[i-1] // dp[0][j] = 1 for j = 0, 1, 2, ..., sum public static int countDP_1st(int[] coins, int coinKinds, int sum){ int[][] dp = new int[coinKinds+1][sum+1]; for(int i=0; i<=coinKinds; i++){ for(int j=0; j<=sum; j++){ dp[i][j] = 0; } } for(int i=0; i<=coinKinds; i++){ dp[i][0] = 1; } for(int i=1; i<=coinKinds; i++){// 币的面值 for(int j=1; j<=sum; j++){// 要凑成的数量 dp[i][j] = 0; for(int k=0; k<=j/coins[i-1]; k++){ dp[i][j] += dp[i-1][j-k*coins[i-1]]; } } } return dp[coinKinds][sum]; } //====================================第二种思路 // Return the count of ways we can sum coins[0...m-1] coins to get sum public static int countRec_2nd(int coins[], int coinKinds, int sum){ if(sum == 0){// If n is less than 0 then no solution exists return 1; } if(sum < 0){// If n is less than 0 then no solution exists return 0; } if(coinKinds<=0 && sum>=1){// If there are no coins and n is greater than 0, then no solution exist return 0; } // count is sum of solutions (i) including coins[m-1] (ii) excluding coins[m-1] // 两种情况: // 1. 不使用最后一个硬币,因此实际上就是用少了最后一个硬币的coins来凑sum // 2.使用最后一个硬币,因此sum的总数减少,因为每个硬币都有无数个,所以m不变 return countRec_2nd(coins, coinKinds-1, sum) + countRec_2nd(coins, coinKinds, sum-coins[coinKinds-1]); } public static int countDP2D_2nd(int[] coins, int coinKinds, int sum){ // We need n+1 rows as the table is constructed in bottom up manner using // the base case 0 value case (n = 0) int[][] dp = new int[sum+1][coinKinds]; // Fill the entries for 0 value case (sum = 0) for(int i=0; i<coinKinds; i++){ dp[0][i] = 1; } // Fill rest of the table entries in bottom up manner for(int i=1; i<=sum; i++){// sum for(int j=0; j<coinKinds; j++){// coins m // Count of solutions including S[j] int x = (i-coins[j]>=0) ? dp[i-coins[j]][j] : 0;// 要满足i-coins[j]>=0 // Count of solutions excluding S[j] int y = (j>=1) ? dp[i][j-1] : 0;// 要满足j-1>=0 dp[i][j] = x + y; } } return dp[sum][coinKinds-1]; } public static int countDP1D_2nd(int[] coins, int coinKinds, int sum){ // dp[i] will be storing the number of solutions for // value i. We need n+1 rows as the table is constructed // in bottom up manner using the base case (n = 0) int[] dp = new int[sum+1]; dp[0] = 1;// Base case (If given value is 0) // Pick all coins one by one and update the table[] values // after the index greater than or equal to the value of the // picked coin for(int i=0; i<coinKinds; i++){// coins m for(int j=coins[i]; j<=sum; j++){// sum dp[j] += dp[j-coins[i]]; } } return dp[sum]; } }
2 What is the smallest number of coins to change? 如果换,最少会有多少枚硬币?
http://www.columbia.edu/~cs2035/courses/csor4231.F11/dynamic.pdf
C[p] = min{C[p-di]+1}
package DP;import java.util.Arrays;/**A country has coins with denominations1 = d1 < d2 < · · · < dk. You want to make change for n cents, using the smallest number */public class CoinChange2 {public static int MEM[] = new int[10001]; // Can support up to 10000 peso value public static int coins[] = {1, 2, 3}; // Available coin denominations public static void main(String[] args) { int n = 4; System.out.println(minCoins(n)); System.out.println(minCoins_DP(n)); } // 记忆化搜索,top-down 递归 public static int minCoins(int n) { if(n < 0) return Integer.MAX_VALUE -1; else if(n == 0) return 0; else if(MEM[n] != 0) // If solved previously already return MEM[n]; else { // Look for the minimal among the different denominations MEM[n] = 1+minCoins(n-coins[0]); for(int i = 1; i < coins.length; i++) MEM[n] = Math.min(MEM[n], 1+minCoins(n-coins[i])); return MEM[n]; } } // bottom-up DPpublic static int minCoins_DP(int n){int[] minCoins = new int[n+1];Arrays.fill(minCoins, Integer.MAX_VALUE);// 第一个硬币minCoins[0] = 0;// 算出n前的每一个可换硬币的数量for(int i=1; i<=n; i++){// 根据递推公式,看看硬币可拆分的可能性for(int j=0; j<coins.length; j++){if(coins[j] <= i){minCoins[i] = Math.min(minCoins[i], 1+minCoins[i-coins[j]]);}}}return minCoins[n];}}
0 0
- DP7 两道换硬币的问题 Coin Change @geeksforgeeks
- Coin Change 2-硬币问题
- Coin Change【硬币找零】
- uva674 - Coin Change(硬币找零)
- Coin Change - UVa 674 换硬币的dp
- LeetCode 322. Coin Change(兑换硬币)
- 322. Coin Change(硬币找零)
- HDU2069 & UVA 674 Coin Change(换硬币 dp 入门经典水题,背包问题)
- UVA 674 Coin Change 换硬币 经典dp入门题
- leetcode 322. Coin Change-硬币交换|动态规划
- 动态规划之硬币兑换(Coin Change)
- ZJU2034 False Coin - 称硬币问题
- Coin Change
- Coin Change
- Coin change
- Coin Change
- Coin change
- Coin Change
- Xcode 5 中引入 C++ 模板代码无法编译通过的问题解决
- android 对sqlite数据库的增删改查
- How to Install Oracle Java on Ubuntu Linux
- FWNX - 补码 反码 负数 在电脑中的存放规则- 边界值
- 20131224-第十七天
- DP7 两道换硬币的问题 Coin Change @geeksforgeeks
- ProgressBar 水平进度条(初步)
- ProgressBar 颜色的设置
- DP8 矩阵链相乘 Matrix Chain Multiplication @geeksforgeeks
- DP9 二项式系数 Binomial Coefficient @geeksforgeeks
- DP10 0-1背包问题 0-1 Knapsack Problem @geeksforgeeks
- JQuery Highcharts图表控件的使用简介
- JQuery Highcharts图表控件的使用
- highcharts 高级应用(生成动态曲线)