📜  Java硬币找零程序 | DP-7(1)

📅  最后修改于: 2023-12-03 15:02:05.756000             🧑  作者: Mango

Java硬币找零程序 | DP-7

简介

这是一篇介绍Java实现硬币找零程序的文章,我们将使用动态规划算法实现该程序,并通过详细的代码讲解,使读者能够深入了解该算法的实现过程。

动态规划算法

动态规划(DP)是一种常用于优化问题的解法。它通常用于寻找最优解和最大收益等问题。 动态规划算法的基本思想是将问题拆分成更小的问题,并将之前计算出的结果保存下来以供今后使用。该算法通常用于解决需要找到最佳方案或最小代价的问题。在硬币找零程序中,我们可以使用动态规划来解决问题。

动态规划解法

我们假设有n种不同面值的硬币c1, c2, ..., cn,我们要找的总面值是V。如果我们最少需要的硬币数量为m,那么我们需要找出使用多少个硬币可以组成面值为V。

我们可以定义一个m x (V+1)的二维数组table,其中table[i][j]代表使用前i种硬币可以组成的面值为j所需的最少硬币数量。初始情况下,我们可以将数组的所有元素设为无穷大,除了table[0][0]。如果一个面值为j不能使用前i种硬币来表示,那么table[i][j]的值就等于table[i-1][j];否则,我们可以选择使用第i种硬币,这时table[i][j]的值就等于table[i][j-ci]+1,其中ci是第i种硬币的面值。

请看以下示例代码:

public static int coinChange(int[] coins, int amount) {
    int[][] table = new int[coins.length + 1][amount + 1];
    for (int i = 0; i <= coins.length; i++) {
        table[i][0] = 0;
    }
    for (int j = 1; j <= amount; j++) {
        table[0][j] = Integer.MAX_VALUE;
    }
    for (int i = 1; i <= coins.length; i++) {
        for (int j = 1; j <= amount; j++) {
            if (j < coins[i-1]) {
                table[i][j] = table[i-1][j];
            } else {
                table[i][j] = Math.min(table[i-1][j], table[i][j-coins[i-1]]+1);
            }
        }
    }
    return table[coins.length][amount] == Integer.MAX_VALUE ? -1 : table[coins.length][amount];
}

在上面的代码中,我们通过创建一个m x (V+1)的二维数组来存储所需的最少硬币数量,其中m是硬币种数,V是要找的总面值。我们首先将数组的第一列设置为0,表示要求找零为0时,对应硬币数量为0。然后,我们将数组的第一行,除了table[0][0]外,所有的元素都设置为无穷大,因为要求找零时不可能使用硬币数量为0。对于其他元素,我们使用上面的公式来计算数组的值。最终,我们返回table[m][V]的值,这是使用全部的硬币来凑成总面值时所需的最少硬币数量。

测试示例

我们可以使用以下测试用例来测试我们的程序的正确性:

int[] coins = {1, 2, 5};
int amount = 11;
int result = coinChange(coins, amount);
System.out.println("找零 " + amount + " 元需要的最少硬币数为:" + result);

输出结果应该为:

找零 11 元需要的最少硬币数为:3

这表明,我们需要使用3个硬币才能凑成11元钱,即两个5元硬币和一个1元硬币。

总结

在本文中,我们介绍了Java实现硬币找零程序的动态规划解法,通过创建一个二维数组来存储所需的最少硬币数量,我们可以有效地解决硬币找零问题。 动态规划算法是一种有用的技术,可用于解决需要找到最佳方案或最小代价的问题。 在实现硬币找零程序时,动态规划算法使我们能够以时间和空间更有效的方式,找到最少需要的硬币数。