简体   繁体   中英

Dynamic Coin Change Algorithm (Optimal Results)

I have been given this part of code on Dynamic Programming (that finds the best combination of coin change. For example if we have two coins of value 3 and 4 --> {3,4}; and the amount that we want to make change is for example sum=11, the answer is that we need in total 3 coins (2 coins with value=4 and 1 coin with value=3). The code below is working good, but not exactly as I want to.

I am trying to reverse engineering the code bellow so that it will provide a more clear answer like this:

Total coins:3 , #of Coins with value "3" = 1, #of Coins with value "4" = 2

The number of total coins for the given amount can be found from this array minimum[sum]. But the rest information I am trying to get (which coin is what value) , seems almost impossible to find. Also from array coins[sum][0] I can only find the last coin used , in this example its the 3 .

Inputs: sum=11 ,int[] valueCoins = new int[]{3,4}; 
Output:
1 10011 0(0)
2 10011 0(0)
3 1 3(0)
4 1 4(0)
5 10011 0(0)
6 2 3(3)
7 2 3(4)
8 2 4(4)
9 3 3(6)
10 3 3(7)
11 3 3(8)

As you can see it checks everything from 1 to 11, but then it reaches 11 it stores the correct amount of coins (3) and the last coin used (3).

public class MinimumCoin {

    public static void main(String args[]){

        int[] valueCoins = new int[]{3,4};
        int sum = 11;
        int[] minimum = new int[sum+1];
        int[][] coins = new int[sum+1][2];

        /* initializing the minimum of every sum to infinity */
        for(int i = 1; i < minimum.length; i++){
            minimum[i] = sum + 10000;
        }
        /* initializing that for minumum sum of zero, 0 coin is required */
        minimum[0] = 0;

        for(int i = 1; i <= sum; i++){
            for(int j = 0; j <valueCoins.length; j++){
                if(valueCoins[j] == i){
                    minimum[i] = 1;
                    coins[i][0] = i;
                    coins[i][1] = 0;
                }
                else if((valueCoins[j] < i) && (((minimum[i-valueCoins[j]]) + 1) < minimum[i])){

                    minimum[i] = (minimum[i-valueCoins[j]]) + 1;
                    coins[i][0] = valueCoins[j];
                    coins[i][1] = (i-valueCoins[j]);
                }
            }
        }

        for(int k = 1; k < minimum.length; k++){
            System.out.println( k + " " + minimum[k] + " " + coins[k][0] +"("+ coins[k][1] +")");
        }
    }
}

Thanks for any input!

~Regards, S

The problem is that the values in coins are the value of the coins, not the counts. coins :

0 0 0 3 0 0 3 3 4 3 3 3 
0 0 0 0 4 0 3 4 4 6 7 8

So you need to reconstruct the counts:

for(int k = 1; k < minimum.length; k++)
{
   int count1 = 0, count2 = 0, pos = k;
   if (coins[pos][1] > 0)
      while (true)
      {
         if (coins[pos][0] == 3) count1++;
         if (coins[pos][0] == 4) count2++;
         if (coins[pos][1] == 3) count1++;
         if (coins[pos][1] == 4) count2++;
         if (coins[pos][1] < 5) // stop when 0/3/4
            break;
         pos = coins[pos][1];
      }
   System.out.println(k + " " + minimum[k] + " " +
                      count1 + " of coin 3, " + count2 + " of coin 4");
}

These are also options to solve the problem:

  • Have rows for each number of occurrences of a coin. If you have 2 coins, and each can appear 5 times, you'll have 5x2 = 10 rows.

  • Have rows as follows:

    • row 1 = 1 of coin 1
    • row 2 = 1 of coin 2
    • row 3 = 2 of coin 1
    • row 4 = 2 of coin 2
    • row 5 = 4 of coin 1
    • row 6 = 4 of coin 2
    • row 7 = 8 of coin 1
    • row 8 = 8 of coin 2
    • ...

The latter is sightly more complex but preferred since there will be a lot less rows for a lot more coins.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM