【完全背包问题】可视化

没问题,我来用更简单的方式解释一下。

问题回顾

你需要计算凑成一个目标金额所需的最少硬币数量。假设我们有硬币面额数组 coins = [1, 2, 5] 和目标金额 amount = 11

解决方案

我们使用动态规划来解决这个问题。虽然实现中通常使用一维数组,但理解时可以将其看作一个逐步构建的二维数组。这里我们会把一维数组的思想转化为二维数组的方式来帮助理解。

动态规划表

  1. 定义二维数组

    • 假设有一个二维数组 dpdp[i][j] 表示凑成金额 i 时,使用前 j 种硬币的最小硬币数。
    • 这个数组的行表示金额,从 0 到 amount
    • 列表示硬币的种类(在这个例子中是 1, 2, 和 5)。
  2. 初始化

    • dp[0][j] = 0,因为凑成金额 0 不需要任何硬币。
    • 对于其他金额,初始化为一个很大的数(表示最初无法用硬币凑成该金额)。
  3. 填充表格

    • 对于每个金额 i,尝试使用每种硬币 coin 来更新 dp[i][j]
    • 公式为:dp[i][j] = min(dp[i][j], dp[i - coin][j] + 1)

举例

假设硬币面额为 1, 2, 5,目标金额为 11。我们逐步填充一个二维数组:

初始化二维数组
  • 行是金额从 0 到 11。
  • 列是硬币种类:1、2、5。
金额/硬币 | 1 | 2 | 5
---------|---|---|---
0        | 0 | 0 | 0
1        | 1 | ∞ | ∞
2        | 2 | 1 | ∞
3        | 3 | 2 | ∞
4        | 4 | 3 | ∞
5        | 5 | 4 | 1
6        | 6 | 5 | 2
7        | 7 | 6 | 3
8        | 8 | 7 | 4
9        | 9 | 8 | 5
10       | 10| 9 | 6
11       | 11| 10| 7
填充过程
  1. 金额为 1

    • 使用硬币 1 时,dp[1][0] = dp[0][0] + 1 = 1(用一个 1 元硬币)
  2. 金额为 2

    • 使用硬币 1 时,dp[2][0] = dp[1][0] + 1 = 2
    • 使用硬币 2 时,dp[2][1] = dp[0][1] + 1 = 1(用一个 2 元硬币,比较取最小值)
  3. 金额为 5

    • 使用硬币 1 时,dp[5][0] = dp[4][0] + 1 = 5
    • 使用硬币 2 时,dp[5][1] = dp[3][1] + 1 = 4
    • 使用硬币 5 时,dp[5][2] = dp[0][2] + 1 = 1(用一个 5 元硬币,最少)
  4. 继续填充,直到金额 11。

最终结果

  • dp[11] 表示凑成金额 11 时,最少需要的硬币数。
  • 从表中最后一行,可以看到使用硬币 5 最少。

简化

实际实现中,我们用一维数组 dp 代替二维数组,节省空间:

  • dp[i] 表示凑成金额 i 的最少硬币数。
  • 从金额 0 开始逐步计算到 amount

希望这个简化的例子能帮助你理解!如果还有疑问,随时告诉我。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值