Dynamic Programming - making change

T. Thomas picture T. Thomas · Nov 7, 2011 · Viewed 12.8k times · Source

I'm having trouble figuring out my last section of code for a Dynamic Coin Changing Problem. I have included the code below.

I can't figure out the last else. Should I just use the greedy algorithm at that point or can I calculate the answer from values already in the table? I've worked hard on trying to understand this problem and I think I'm pretty close. The method finds the minimum amount of coins needed to make a certain amout of change by creating a table and using the results that are stored in the table to solve the larger problem without using recursion.

public static int minCoins(int[] denom, int targetAmount){
    int denomPosition; // Position in denom[] where the first spot
                       // is the largest coin and includes every coin
                       // smaller.
    int currentAmount; // The Amount of money that needs to be made
                       // remainingAmount <= initalAmount
    int[][] table = new int[denom.length][targetAmount+1];
    for(denomPosition = denom.length-1 ; denomPosition >= 0 ; denomPosition--) {
        for(currentAmount = 0 ; currentAmount <= targetAmount ; currentAmount++){
            if (denomPosition == denom.length-1){
                table[denomPosition][currentAmount] = 
                     currentAmount/denom[denomPosition];
            }
            else if (currentAmount<denom[denomPosition]){
                table[denomPosition][currentAmount] = 
                     table[denomPosition+1][currentAmount];
            }
            else{           
                table[denomPosition][currentAmount] = 
                     table[denomPosition+1][currentAmount]-
                     table[denomPosition][denom[denomPosition]]-1;
            }
        }
    }
    return table[0][targetAmount];
}

Answer

&#211;scar L&#243;pez picture Óscar López · Nov 7, 2011

You don't need to switch to a greedy algorithm for solving the coin changing problem, you can solve it with a dynamic programming algorithm. For instance, like this:

public int minChange(int[] denom, int targetAmount) {

    int actualAmount;
    int m = denom.length+1;
    int n = targetAmount + 1;
    int inf = Integer.MAX_VALUE-1;

    int[][] table = new int[m][n];
    for (int j = 1; j < n; j++)
        table[0][j] = inf;

    for (int denomPosition = 1; denomPosition < m; denomPosition++) {
        for (int currentAmount = 1; currentAmount < n; currentAmount++) {
            if (currentAmount - denom[denomPosition-1] >= 0)
                actualAmount = table[denomPosition][currentAmount - denom[denomPosition-1]];
            else
                actualAmount = inf;
            table[denomPosition][currentAmount] = Math.min(table[denomPosition-1][currentAmount], 1 + actualAmount);
        }
    }

    return table[m-1][n-1];

}