0
votes

I am trying to solve similar to this problem but with some modifications:

"Given a value V, if we want to make a change for V cents, and we have an infinite supply of each of C = { C1, C2, .. , Cm} valued coins, what is the minimum number of coins to make the change?"

Input: coins[] = {25, 10, 5}, V = 30

Output: Minimum 2 coins required

We can use one coin of 25 cents and one of 5 cents

In my case instead of just an array of numbers I have an array of objects. That in each object I have a qty and price. I want to print the minimum number of objects that form the given qty, and after that print the price, something like:

2 x 5 9.95

1 x 3 5.95

I came to this code but I cannot find how to complete the task:

public static void main(String[] args) {
        Product croissant = new Product("Croissant", "CF", null);

        Pack CF_1 = new Pack(3, 5.95);
        Pack CF_2 = new Pack(5, 9.95);
        Pack CF_3 = new Pack(9, 16.99);
        croissant.addPack(CF_1);
        croissant.addPack(CF_2);
        croissant.addPack(CF_3);

        System.out.println(minCoins(croissant, 13));
    }

    static int minCoins(Product product, int V) {
        // table[i] will be storing
        // the minimum number of coins
        // required for i value. So
        // table[V] will have result
        int table[] = new int[V + 1];

        // Base case (If given value V is 0)
        table[0] = 0;

        // Initialize all table values as Infinite
        for (int i = 1; i <= V; i++)
            table[i] = Integer.MAX_VALUE;

        // Compute minimum coins required for all
        // values from 1 to V
        for (int i = 1; i <= V; i++) {
            // Go through all coins smaller than i
            for (Pack pack : product.packList) {
                if (pack.qty <= i) {
                    int sub_res = table[i - pack.qty];
                    if (sub_res != Integer.MAX_VALUE
                            && sub_res + 1 < table[i])
                        table[i] = sub_res + 1;
                }
            }
        }
        return table[V];
    }
1

1 Answers

0
votes

You could get the list of packs that contribute to the minimum coins like below:

You start with given V then you look for the pack at which the table has value that is lesser by 1, because to reach V you must have had a value somewhere that is 1 lesser. If you found one, add it to the list, and reduce the next V by the quantity of the pack you found and continue.

Code is :

   void printList(int[] table, Product product, int V) {
      List<Pack> list = new ArrayList<>();
      if ( table[V] == Integer.MAX_VALUE ) return list;
      while ( V > 0 ) {
        for (Pack pack : product.packList) {
          if ( V >= pack.qty && table[V-pack.qty] == table[V] - 1 ) {
            list.add(pack);
            V = V-pack.qty;
            break;
          }
        }
      }
    }

For your example of V = 13 , the list would be : [{3, 5.95}, {5, 9.95}, {5, 9.95}] This is assuming you implement toString() of the Pack class as;

public String toString() {
  return "{" + this.qty + "," + this.price + "}";
}

You can reduce your list to a map if you would like using Collectors

something like : list.stream().collect(Collectors.groupingBy(Pack::getQty))