使用特定硬币形成金额的方式数

时间:2017-12-28 18:51:41

标签: java

我正在努力解决这个问题。 http://www.lintcode.com/en/problem/coin-change-ii/#

这是动态编程可解决的标准硬币更改问题。目标是找到使用无限组硬币创建金额的方式的数量,其中每个硬币具有特定值。我创建了以下解决方案:

public int change(int amount, int[] coins) {
    // write your code here
    int[] dp = new int[amount + 1];
    dp[0] = 1;


    // for(int coin : coins) {
    //     for(int i = 1; i <= amount; i++) {
    //         if(i >= coin) dp[i] += dp[i-coin];
    //     }
    // }


    for(int i = 1; i <= amount; i++) {
        for(int coin : coins) {
            if(i >= coin) dp[i] += dp[i-coin];
        }
    }

    return dp[amount];
}

为什么第一个for循环给出了正确答案,但第二个没有?我在这里错过了什么?难道答案不一样吗?你能提供视觉来帮助我吗?看到&#34;为什么循环的第二个不正确? 当金额= 8且硬币= [2,3,8]时,当使用第二个for循环技术不正确时,输出为5时为3。

谢谢。

2 个答案:

答案 0 :(得分:0)

让我们考虑首先运作的循环:

for(int coin : coins) {
    for(int i = 1; i <= amount; i++) {
         if(i >= coin) dp[i] += dp[i-coin];
     }
}

外部循环的每次迭代都会获得一个值的硬币,并找出达到硬币值和amount之间任何值的方式的数量,并将该硬币添加到前一次迭代的结果中。

考虑您的amount = 8coins = [2,3,8]示例:

数组初始化为

index    0 1 2 3 4 5 6 7 8
value    1 0 0 0 0 0 0 0 0

这意味着没有任何硬币,我们可以达到的唯一金额是0,我们只有一种方法可以达到该金额(0 2s,0 3s,0 8s)。

现在我们只用值2的硬币找到我们可以达到的金额:

index    0 1 2 3 4 5 6 7 8
value    1 0 1 0 1 0 1 0 1

我们可以达到任何均匀数量并不奇怪。对于每个这样的金额,我们只有一种方法可以达到这个数量(1 2到达2,2 2到达4,等等。)

现在我们找到了我们可以用值为2或3的硬币达到的金额。如果我们已经找到达到k-3金额的方法,我们可以使用3的硬币达到金额k。

下面我展示了达到0到8之间每个值的方法的数量,并指定每种组合中使用的每种类型的硬币数量。

index    0   1   2   3   4   5   6   7   8
value    1   0   1   1   1   1   2   1   2

         0x2 -   1x2 0x2 2x2 1x2 3x2 2x2 4x2
         0x3 -   0x3 1x3 0x3 1x3 0x3 1x3 0x3

                                 or      or

                                 0x2     1x2
                                 2x3     3x3

最后,在最后一次迭代中,我们考虑8的硬币。它只能用于达到8的数量,所以我们得到最终的结果:

index    0   1   2   3   4   5   6   7   8
value    1   0   1   1   1   1   2   1   3

交换循环时:

for(int i = 1; i <= amount; i++) {
    for(int coin : coins) {
        if(i >= coin) dp[i] += dp[i-coin];
    }
}

您将加入硬币的订单带入游戏中。例如,可以通过先拿硬币2然后硬币3,或先拿硬币3然后硬币5来达到金额5.因此dp[5]的值现在是2。

同样,dp[8]会产生5,因为您可以使用以下任何一组硬币:

2+3+3
3+2+3
3+3+2
2+2+2+2
8

原始循环不区分2+3+33+2+33+3+2。因此产出不同。

答案 1 :(得分:0)

private static int coinChange(int[] coins, int sum) {

        int size = coins.length;
        int[][] arr = new int[size + 1][sum + 1];

        // Applying the recursive solution:
        for(int i = 1; i < size +1; i++){
            for(int j = 1; j < sum +1; j++) {
                arr[i][0] = 1;

                if (coins[i - 1] > j) {
                    arr[i][j] = arr[i - 1][j];
                } else
                    arr[i][j] = arr[i - 1][j]+arr[i][j - coins[i - 1]] ;
            }}

        return arr[size][sum];enter code here