您的位置:首页 > 其它

8.11 Coins

2015-10-31 02:31 253 查看
For example, if we have n = 100 cents:

makeChange(100) = makeChange(100 w/ 0 quater) + makeChange(100 w/ 1 quater) + makeChange(100 w/ 2 quater) + makeChange(100 w/ 3 quater) + makeChange(100 w/ 4 quater). What’s more, makeChange(100 w/ 1 quater) = makeChange(75 w/ 0 quarter).

Under each sub problem we have makeChange(100 w/ 0 quarter) = makeChange(100 w/ 0 quarter, 1 dime to 10 dime)…

Than’s mean: we can solve the question by accumulating all there results!

//c++
int helper(vector<int>& coins, int n, int idx){
if(idx >= coins.size() - 1) return 1;
int cntWays = 0;
for (int i = 0; i*coins[idx] <= n; ++i) {
cntWays += helper(coins, n - i*coins[idx], idx + 1);
}
return cntWays;
}
int makeChange(int n){
vector<int> coins = {25, 10, 5, 1};
return helper(coins, n, 0);
}


public static int makeChangeHelper(int[] coins, int n, int idx){
if(idx >= coins.length-1) return 1;
int amount = coins[idx], cntWays = 0;
for(int i = 0; i*amount <= n; ++i){
cntWays += makeChangeHelper(coins, n-i*amount, idx + 1);
}
return cntWays;
}

public static int makeChange(int n, int[] coins){
return makeChangeHelper(coins, n, 0);
}


However, the above code is not that optimal, because we keep recall makeChange(100 w/ …) several times. Therefore, the possible method to optimize it is by using extra space O(kn). By recording the certain amount ways, we will increase the speed. There is a basically the trade-off between memory and speed.

public static int makeChangeHelper(int[] coins, int amount, int idx, int[][] mp){
if(mp[amount][idx] > 0) return mp[amount][idx];
if(idx >= coins.length-1) return 1;
int cntWays = 0;
for(int i = 0; i * coins[idx] <= amount; ++i){
cntWays += makeChangeHelper(coins, amount - i*coins[idx], idx+1, mp);
}
mp[amount][idx] = cntWays;
return cntWays;
}
public static int makeChange(int n, int[] coins){
int[][] mp = new int[n+1][coins.length];
return makeChangeHelper(coins,n,0,mp);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Recursion