`
阅读更多

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.

For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.

 

We are trying to count the number of distinct sets.

Since order does not matter, we will impose that our solutions (sets) are all sorted in non-decreasing order (Thus, we are looking at sorted-set solutions: collections).

For a particular N and S=\{S_{1},S_{2},\ldots ,S_{m}\} (now with the restriction that S_{1}<S_{2}<\ldots <S_{m}, our solutions can be constructed in non-decreasing order), the set of solutions for this problem, C(N,m), can be partitioned into two sets:

  • There are those sets that do not contain any S_{m} and
  • Those sets that contain at least 1 S_{m}

If a solution does not contain S_{m}, then we can solve the subproblem of N with S=\{S_{1},S_{2},\ldots ,S_{{m-1}}\}, or the solutions of C(N,m-1).

If a solution does contain S_{m}, then we are using at least one S_{m}, thus we are now solving the subproblem of N-S_{m}S=\{S_{1},S_{2},\ldots ,S_{m}\}. This is C(N-S_{m},m).

Thus, we can formulate the following:

C(N,m)=C(N,m-1)+C(N-S_{m},m)

with the base cases:

  • C(N,m)=1,N=0 (one solution -- we have no money, exactly one way to solve the problem - by choosing no coin change, or, more precisely, to choose coin change of 0)
  • C(N,m)=0,N<0 (no solution -- negative sum of money)
  • C(N,m)=0,N\geq 1,m\leq 0 (no solution -- we have money, but no change available)

先上最优解:

public int coinChange(int[] S, int N) {
	int[] f = new int[N+1];
	f[0] = 1;
	for(int i=0; i<S.length; i++) {
		for(int j=S[i]; j<=N; j++) {
			f[j] += f[j-S[i]];
		}
	}
	return f[N];
}

 

Recursive Method:

// Returns the count of ways we can sum  S[0...m-1] coins to get sum n
int count( int S[], int m, int n ) {
    // If n is 0 then there is 1 solution (do not include any coin)
    if (n == 0)
        return 1;
     
    // If n is less than 0 then no solution exists
    if (n < 0)
        return 0;
 
    // If there are no coins and n is greater than 0, then no solution exist
    if (m <=0 && n >= 1)
        return 0;
 
    // count is sum of solutions (i) including S[m-1] (ii) excluding S[m-1]
    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
}

 

Dynamic Programming: 

int count( int S[], int m, int n )
{
    int i, j, x, y;
 
    // We need n+1 rows as the table is consturcted in bottom up manner using 
    // the base case 0 value case (n = 0)
    int table[n+1][m];
    
    // Fill the enteries for 0 value case (n = 0)
    for (i=0; i<m; i++)
        table[0][i] = 1;
 
    // Fill rest of the table enteries in bottom up manner  
    for (i = 1; i < n+1; i++)
    {
        for (j = 0; j < m; j++)
        {
            // Count of solutions including S[j]
            x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;
 
            // Count of solutions excluding S[j]
            y = (j >= 1)? table[i][j-1]: 0;
 
            // total count
            table[i][j] = x + y;
        }
    }
    return table[n][m-1];
}

 

Time Complexity: O(mn)

Following is a simplified version of method 2. The auxiliary space required here is O(n) only.

int count( int S[], int m, int n )
{
    // table[i] will be storing the number of solutions for
    // value i. We need n+1 rows as the table is consturcted
    // in bottom up manner using the base case (n = 0)
    int table[n+1];
 
    // Initialize all table values as 0
    memset(table, 0, sizeof(table));
 
    // Base case (If given value is 0)
    table[0] = 1;
 
    // 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<m; i++)
        for(int j=S[i]; j<=n; j++)
            table[j] += table[j-S[i]];
 
    return table[n];
}

Reference: 

http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/

http://www.algorithmist.com/index.php/Coin_Change

分享到:
评论

相关推荐

    p1-Coin-Change.rar_Change_coin change

    Coin Change問題 計算錢幣兌換問題 有幾種可能

    coin_change_problem

    Dynamic Programming Solution to the Coin Changing Problem

    LeetCodeTrain:这是来自LeetCode的已解决任务的存储库

    这是来自LeetCode的已解决任务的存储库使用Java语言解决任务 CoinChange.java - //leetcode....

    LeetCode-Coin-Change

    LeetCode-Coin-Change

    TechnicalInterviews:我对技术面试问题的解决方案

    技术面试 ...│ │ ├── CoinChange.java │ │ └── WildcardPatternMatching.java │ ├── HashTables │ │ ├── CompoundWord.java │ │ └── RansomNote.java │ ├─

    hackerrank:解决HackerRank练习挑战的方法

    解决HackerRank练习挑战的方法 音轨 演算法 暖身 挑战 解决方案 时间复杂度 空间复杂度 O(1) O(1) 上) O(1) O(1) O(1) 上) O(1) 上) O(1) 正负 Java 上) O(1) ... 女王的进攻

    leetcode打不开-leetcode:leetcode

    Change) Tip4: backtrace or K sum remove duplicates if i != 0 and n == nums[i-1]: (#15. 3Sum) if idx &gt; start and nums[idx] == nums[idx-1]: continue (#40. Combination Sum II) Tip5: 鸽笼原理要记得,如果...

    Leetcode扑克-Algos:我最喜欢的一些算法问题-JS&Python

    Change JS (组合,动态自下而上) 组字谜JS 水容器JS 第一个缺失的正JS 水果入篮JS CodeSignal 街机问题 介绍 10 - 常见字符计数JS & Python 13 - 在括号中反转JS & Python 14 - 交替求和JS & Python 15 - 添加边框...

    LeetCode判断字符串是否循环-data-structure-and-algo:C++中的数据结构和算法

    CoinChange(#322), EditDistance(#72) 图 : 集合的合并(直接求并、按大小求并和按深度求并)、根搜寻(路径压缩) : 有向图和无向图的邻接表表示方法 : 图的深度优先和广度优先搜索(假设图用邻接表矩阵表示)、拓扑...

    leetcode和oj-Dynamic-Programming-9C:九章算法动态规划专题相关代码

    leetcode 和 oj 简介 :balloon: 题目为九章算法DP专题中讲到的...coinChange(vector&lt;int&gt;& coins, int amount) { sort(coins.begin(),coins.end()); //不得不忍受一个排序的时间复杂度 if(amount == 0) { return 0; }

    leetcode岛屿面积-LeetCode:LeetCode题目集

    CoinChange DFS(Deep First Search)深度优先搜索 岛屿的最大面积(MaxAreaOfIsland) BFS(Breath First Search)广度优先搜索 图论 最短路径 最小生成树 动态规划(dp) 最长上升子序列(lengthOfLIS) 基础技巧 ...

    lrucacheleetcode-leetcode-practice:包括C或PHP或Go

    lru cache leetcode LeetCode 个人练习 struct algorithm 目录分为 2 个目录,分别是数据结构和算法 数据结构 存放一些底层语言需要实现的基本数据结构,算法可能会用得上的 ...coinChange subdomainVisits

    tryalgo:准备节目竞赛的算法和数据结构

    算法问题解决 用于准备编程比赛的算法和数据结构(例如ACM-ICPC,)和编码采访。 克里斯托弗·杜尔(ChristophDürr)和吉尔·詹恩·维(Jill...print ( coin_change ([ 3 , 5 , 11 ], 29 )) # True because 29 = 6 x 3

    dynamic-programming:动态编程

    动态编程递归无重复每个子问题只能评估一次天真的递归方法由于重复而花费指数时间自上而下的回忆这是递归的深度优先搜索实现缓存重复工作自下而上基于依赖图将递归转换为依赖图它是有向无环图您可以使用拓扑排序对......

    lrucacheleetcode-leetcode-in-go:leetcode-in-go

    coin-change-ii-0518 组合和-iv-0377 解码方式-0091 盗家贼-0198 盗家贼-ii-0213 jump-game-0055 最长公共子序列1143 最长公共子串 最长递增子序列0300 最大积子阵列0152 最大子阵列-0053 唯一路径-0062 word-break-...

    音效随机生成器

    捡起/投币(PickUp/Coin) 激光/射击(Laser/Shoot) 爆炸(Explosion) 能量升级(PowerUp) 击中/受伤(Hit/Hurt) 弹开/选择(Blip/Select) 突变(mutate,生成当前音效的相似效果) 随机化(Randomizc)...

    算法导论第三版

    coins needed to make change for a given amount, we can repeatedly select the largest-denomination coin that is not larger than the amount that remains. A greedy approach provides an optimal solution ...

    jdcookie.js下载最新版

    长期 京豆变动通知 jd_bean_change.js 长期 领京豆额外奖励&抢京豆 jd_bean_home.js 长期 京东多合一签到 jd_bean_sign.js 长期 东东超市兑换奖品 jd_blueCoin.js 长期 口袋书店 jd_bookshop.js 长期 京东汽车赛点...

    Cash_register:收银机(FCC-2的一部分)

    freeCodeCamp-算法和数据结构项目5-收银机设计一个收银机抽屉函数checkCashRegister(),该函数将购买价格作为第一个参数(价格),将... 返回{ status : "INSUFFICIENT_FUNDS" , change : [ ]} 如果抽屉中的现金少于

    pulp-1.6.8.zip

    Solver pulp.solvers.COIN_CMD unavailable Solver pulp.solvers.COINMP_DLL unavailable Testing zero subtraction Testing inconsistant lp solution Testing continuous LP solution Testing maximize ...

Global site tag (gtag.js) - Google Analytics