快速解决凑硬币难题,动态规划算法轻松搞定!

393 阅读2分钟

引言

硬币问题是一个经典的最值问题,即找到凑成硬币总金额的最小硬币数量。在这篇文章中,我们将介绍一种基于动态规划的解决方法。

动态规划思路

在解决硬币问题时,我们可以采用自底向上的动态规划方法。我们首先需要定义一个数组f,其中f[i]表示凑成金额i所需的最小硬币数量。因为硬币数量不可能超过总金额,所以我们初始化f[0]为0。然后,我们通过迭代更新f数组的值,直到计算出f[amount]为止。

在每次迭代中,我们遍历硬币列表coins,并尝试使用当前硬币来凑成总金额i。如果i - coins[j] >= 0,说明我们可以使用当前硬币来凑成总金额i,此时我们需要更新f[i]的值为Math.min(f[i], f[i-coins[j]] + 1)。这个公式的含义是:要凑成总金额i,我们可以先凑成总金额i - coins[j],再加上一个硬币coins[j],即可得到总金额i。而凑成总金额i - coins[j]所需的最小硬币数量为f[i-coins[j]],所以总的硬币数量为f[i-coins[j]] + 1。

最后,当f[amount]为Infinity时,说明凑成总金额amount的方案不存在,返回-1即可。

代码实现

下面是基于动态规划思路的JavaScript代码实现:

const coinChange = function(coins, amount) {
    const f = []
    f[0] = 0;
    for(let i = 1; i <= amount; i++){
        f[i] = Infinity // 先设置为最大值
        for(let j = 0; j < coins.length; j++) {
            if(i - coins[j] >= 0){
                f[i] = Math.min(f[i], f[i-coins[j]] + 1)
            }
        }
    }
    if(f[amount] === Infinity) {
        return -1
    }
    return f[amount]
}

总结

动态规划是解决硬币问题的有效方法之一。通过定义状态转移方程和迭代更新数组的值,我们可以高效地找到凑成总金额的最小硬币数量。在实际应用中,我们可以根据具体问题的规模和要求,选择不同的算法和数据结构来解决问题,以达到最优的效果。