Java 查找构成给定值的最小包数

Java 查找构成给定值的最小包数,java,algorithm,dynamic-programming,Java,Algorithm,Dynamic Programming,我正在尝试解决类似于此问题的问题,但进行了一些修改: “给定一个值V,如果我们想换V美分,并且我们有无限量的C={C1,C2,…,Cm}值硬币,那么换硬币的最小数量是多少?” 输入:硬币[]={25,10,5},V=30 输出:至少需要2枚硬币 我们可以用一枚25美分的硬币和一枚5美分的硬币 在我的例子中,我有一个对象数组,而不仅仅是一个数字数组。每件物品都有数量和价格。 我想打印构成给定数量的最小数量的对象,然后打印价格,类似于: 2x59.95 1 x 35.95 我使用了此代码,但找不到如

我正在尝试解决类似于此问题的问题,但进行了一些修改:

“给定一个值V,如果我们想换V美分,并且我们有无限量的C={C1,C2,…,Cm}值硬币,那么换硬币的最小数量是多少?”

输入:硬币[]={25,10,5},V=30

输出:至少需要2枚硬币

我们可以用一枚25美分的硬币和一枚5美分的硬币

在我的例子中,我有一个对象数组,而不仅仅是一个数字数组。每件物品都有数量和价格。 我想打印构成给定数量的最小数量的对象,然后打印价格,类似于:

2x59.95

1 x 35.95

我使用了此代码,但找不到如何完成任务:

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];
    }
publicstaticvoidmain(字符串[]args){
产品牛角面包=新产品(“牛角面包”,“CF”,空);
包装CF_1=新包装(3,5.95);
包装CF_2=新包装(5,9.95);
包装CF_3=新包装(9,16.99);
羊角面包。添加包(CF_1);
羊角面包。添加包(CF_2);
羊角面包。添加包(CF_3);
系统输出打印(minCoins(牛角面包,13));
}
静态整数分钟硬币(产品,整数V){
//表[i]将存储
//硬币的最小数量
//我的价值是必需的,所以
//表[V]将显示结果
int table[]=新的int[V+1];
//基本情况(如果给定值V为0)
表[0]=0;
//将所有表值初始化为无限

对于(int i=1;i,您可以获得构成最低硬币数量的包装清单,如下所示:

您从给定的
V
开始,然后查找表中的值小于
1
的包,因为要达到
V
,您必须在某个地方有一个小于
1
的值。如果您找到了一个,请将其添加到列表中,并将下一个
V
减少到您找到并保留的包的数量ue

代码是:

   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;
          }
        }
      }
    }
如果您想使用,可以将列表缩减为地图


类似于:
list.stream().collect(Collectors.groupingBy(Pack::getQty))

谢谢您的回答,但是,我不理解解决方案。特别是为什么我需要提供一个参数“int[]table”,您能解释一下吗。还有为什么我需要table[V]?@Sim,
printList
只是一种打印您想要的列表的方法,如果您愿意,您可以将所有这些语句放入
minCoins
方法中,或者调用
printList
方法。您需要
table[V]
,因为这是您必须从哪里开始并获得有助于减少硬币数量的包装的结果。
public String toString() {
  return "{" + this.qty + "," + this.price + "}";
}