Given coins of certain denominations and a total, how many minimum coins would you need to make this total?
Dynamic Programming solution
State: T[i][j]: given the first i coins, the min number of coins needed to make a total of j.
Function:
case 1. T[i][j] = T[i - 1][j], if j < coins[i - 1], the ith coins can't be used;
case 2. T[i][j] = Math.min(T[i - 1][j], 1 + T[i][j - coins[i - 1]]), if j >= coins[i - 1], the ith coins can be used;
Since T[i][j] is set to -1 when we can't get a total of j out of the first i coins. So in case 2, we need to check
if T[i - 1][j] or T[i][j - coins[i - 1]] is negative. If either one of them is negative, then we need to handle
them separately.
The following implementation also includes how to reconstruct one of the optimal solution.
1 import java.util.ArrayList; 2 3 public class CoinChange { 4 private ArrayList<Integer> pickedCoins; 5 public int minCoinsToGetTotal(int[] coins, int total) { 6 if(total == 0) { 7 return 0; 8 } 9 if(total != 0 && (coins == null || coins.length == 0)) { 10 return -1; 11 } 12 int[][] T = new int[coins.length + 1][total + 1]; 13 for(int j = 0; j < T[0].length; j++) { 14 T[0][j] = -1; 15 } 16 for(int i = 0; i < T.length; i++) { 17 T[i][0] = 0; 18 } 19 for(int i = 1; i < T.length; i++) { 20 for(int j = 1; j < T[0].length; j++) { 21 if(j >= coins[i - 1]) { 22 if(T[i - 1][j] >= 0 && T[i][j - coins[i - 1]] >= 0) { 23 T[i][j] = Math.min(T[i - 1][j], 1 + T[i][j - coins[i - 1]]); 24 } 25 else if(T[i - 1][j] < 0 && T[i][j - coins[i - 1]] >= 0) { 26 T[i][j] = 1 + T[i][j - coins[i - 1]]; 27 } 28 else { 29 T[i][j] = T[i - 1][j]; 30 } 31 } 32 else { 33 T[i][j] = T[i - 1][j]; 34 } 35 } 36 } 37 int i = coins.length, j = total; 38 pickedCoins = new ArrayList<Integer>(); 39 if(T[i][j] > 0) { 40 while(T[i][j] != 0) { 41 if(j >= coins[i - 1] && T[i][j - coins[i - 1]] >= 0 && 1 + T[i][j - coins[i - 1]] == T[i][j]) { 42 pickedCoins.add(coins[i - 1]); 43 j -= coins[i - 1]; 44 } 45 else{ 46 i--; 47 } 48 } 49 } 50 return T[coins.length][total]; 51 } 52 }
Related Problems