当前位置: 首页 > 知识库问答 >
问题:

进行更改的最低硬币数量

笪成周
2023-03-14

我正在尝试打印最小数量的硬币来进行更改,如果不可能,请打印-1

在这段代码中,变量int[]c(硬币数组)有面额,我可以用它来计算总金额。

INT总有总和,我需要拿出使用硬币(无限供应)

    public static int mincoinDP(int[] c, int total) {
        int[][] a = new int[c.length + 1][total + 1];

        for (int i = 0; i <= c.length; i++) {
            a[i][0] = 0;
        }
        for (int j = 1; j <= total; j++) {
            a[0][j] = Integer.MAX_VALUE - total;
        }

        for (int i = 1; i <= c.length; i++) {
            for (int j = 1; j <= total; j++) {
                if (c[i - 1] > j) {
                    a[i][j] = Integer.MAX_VALUE - total;
                } else {
                    a[i][j] = Math.min(a[i - 1][j], 1 + a[i][j - c[i - 1]]);
                }
            }
        }

        return a[c.length][total];
    }

对于Sum:4759和Array:{3190836},正确的输出是:59,我的输出是:60

代码中有什么错误?

下面是我的递归解决方案,尝试在DP解决方案中应用相同的逻辑。这里的逻辑似乎也有问题。对于相同的输入,它打印-2147483595

    public static void main(String[] args) {
        int[] array = new int[] {31, 90, 8, 36};
        System.out.println(mincoin(array, 4759, 0));
    }

    public static int mincoin(int[] c, int total, int i) {

        if (total == 0) return 0;
        if (i >= c.length) return Integer.MAX_VALUE;


        int x = Integer.MAX_VALUE, y = Integer.MAX_VALUE;

        if (total - c[i] >= 0) {
            x = 1 + mincoin(c, total - c[i], i);
        }
        y = mincoin(c, total, i + 1);

        return Math.min(x, y);
    }

编辑:代码中的问题有:

  1. DP版本:if(c[i-1]

虽然我不喜欢这个版本的无限,但除了这个,我看不到任何好的方法。

共有2个答案

傅朗
2023-03-14

以防万一有人在寻找解决方案

public int coinChange(int[] coins, int amount) {
    int dp[][] = new int[coins.length+1][amount+1];
    Arrays.sort(coins);
    
    // First column of every row
    for (int i = 0; i < coins.length; ++i) {
        dp[i][0] = 0;
    }

    /*
       Setting this so that this is default max value. We always
       want our dp[i][j] better than this
    */
    for (int j = 0; j <= amount; ++j) {
        dp[0][j] = amount+1;
    }
    
    for (int i = 1; i <= coins.length; ++i) {
        for (int j = 1; j <= amount; ++j) {
            if (coins[i-1] > j) {
               dp[i][j] = dp[i-1][j];   // Take the already best value in above row
            } else {
               dp[i][j] = Math.min(dp[i-1][j], 1 + dp[i][j-coins[i-1]]); // Take the best of above row and using current coin
            }
        }
    }
    if (dp[coins.length][amount] > amount) { // it means we cannot find any coin
        return -1;
    } else {
        return dp[coins.length][amount];
    }
}
锺霍英
2023-03-14

看起来您使用的是动态规划,a[i][j]旨在表示总和为j的最小硬币数量(使用前i个面额)。但我认为你的关系不好。它们应该是:

a[0][j] = 0 if j==0, otherwise infinity

a[i][j] = a[i-1][j] if c[i-1] > j
a[i][j] = min(a[i-1][j], 1 + a[i][j-c[i-1]]) if c[i-1] <= j

主要错误是c[i-1]的if

顺便说一下,有一种更简洁的方法来编写此代码。在伪代码中:

a = new int[total+1]
for int j = 1 to total+1 {
    a[j] = infinity
}
for int coin in coins {
    for j = coin to total+1 {
        a[j] = min(a[j], a[j-coin]+1)
    }
}

它本质上是相同的算法,但是它使用了一个更小的一维数组,并在原地进行了修改。

 类似资料:
  • 所以我对编码不熟悉,我得到了一个任务,我需要做一个程序,用四分之一、一角、五分和一美分给不到一美元的零钱。然而,作业希望程序打印所需的最低硬币数量(例如,如果我输入58美分,那么输出应该是“2个25美分,1个镍和3个便士”,而不是“2个25美分,0个10美分,1个镍和3个便士”。本质上,如果没有某种硬币,那么程序就不应该打印它)。我一直在想如何制作它,这样程序就不会打印任何不必要的硬币。 这就是我

  • 具体而言,问题是: 给定面额数组<代码>硬币[],每个硬币的限制数组<代码>限制[]和数量<代码>金额,返回所需的最小硬币数量,以获取<代码>金额,或者如果不可能,返回空值。另外,用溶液中使用的每个硬币的数量填充数组 这是我的解决方案: 但它一般不起作用。 我的问题是,例如,在这种情况下: 最佳解决方案是: 并且我的算法给出作为结果。换句话说,它失败了,每当在某种情况下,我将不得不使用比可能的更少

  • 当我试图使用DP解决这个经典问题时,我遇到了一个实现问题。该问题给出了一组硬币,并以返回的方式进行了改变。 DP等式类似于以下内容:DP[i]=DP[i-币[j]] 其中DP[i]表示对i进行更改的方式数。 这里有一个简单的实现,这是不正确的: 给定输入:int coin[]={1,5}change=6。 make_change_wrong(硬币,2,6)返回3,但2是正确的。 使用相同的逻辑,我

  • 我有以下问题: 给定一个目标大小N和一些随机生成的硬币的一些面额,这些硬币存储在数组面额[]中,使用动态规划检查是否存在一个最优解决方案,该方案将使用最少的硬币填充整个目标。 这是硬币兑换问题的一个典型例子,但与现实生活中的货币不同,在现实生活中,每种面额都是经过仔细挑选的,因此可以匹配任何目标。事实并非如此。 我熟悉硬币兑换问题中使用的算法,以及如何构造一个动态规划数组来找到解决方案,但我首先如

  • 有很多关于硬币兑换的问题和答案,但我找不到这一个,我想知道这是否是一个硬币兑换的问题。 基本上我有一堆不同的硬币,每个硬币的数量是无限的。 比如说有很多不同的面额。每个堆栈都是无限的。(因此,25摄氏度硬币的数量是无限的,2摄氏度硬币的数量是无限的,等等)。 然而,在每一堆硬币的顶部是一种特殊的硬币,其价值大于(或等于)下面的硬币。如果不在上面使用这枚硬币,我就无法访问下面的硬币。 我试图计算出的

  • 问题:https://leetcode.com/problems/coin-change/ 解决方案:https://repl.it/@Stylebender/HatefulAliceBlueTransverse#index.js 我理解从“按钮式”构建dp阵列解决方案的一般概念流程,但我只是想知道关于第10行: dp[i]=数学。最小值(dp[i],1 dp[i-硬币[j]]; 当你选择当前的第