uva 674 Coin Change(完全背包)

博客介绍了如何使用完全背包算法解决UVA 674题目,该题目要求根据5种不同面值的硬币(1, 5, 10, 25, 50)计算组成给定金额的不同方式数。错误的解法会因为面值重复而导致重复计算,正确的解决方案是使用low(cnt[i - sex[j]])来避免这种情况。" 132291754,19687574,Python爬虫基础:创建简单网页爬虫,"['Python', '爬虫开发', 'Web抓取', 'BeautifulSoup', '网络数据获取']

题目连接:674 - Coin Change


题目大意:有5种硬币, 面值分别为1、5、10、25、50,现在给出金额,问可以用多少种方式组成该面值。


解题思路:每种硬币都有无限个,所以是典型的完全背包, 一开始写的时候没有考虑到面值的重复问题, 打表的时候将金额值逐一去计算, 但又使用到cnt[i] += cnt[i - sex[j]],  然后导致有些组成方式重复考虑进去(这种只适用50以内的, 不会造成面值的的重复考虑, 比如 100, 在sex[j] == 25时, cnt[100] += cnt[75], 但是75里面的组成方式里有可以用面值为50去组成的方案, 所以等下计算sex[j] == 50的时候就重复计算了)

正确的做法是cnt[i] += low(cnt[i - sex[j]])   表示说cnt[i - sex[j]] 中用面值小于等于sex[j]的组成方式种类。写法代码中给出。


#include <stdio.h>
#include <s
这是一个非常关键的问题!我们来深入解释: > 在**完全背包问题**的动态规划实现中,为什么内层循环要从 `j = coin` 开始? --- ### ✅ 简短回答: 因为: > **你不能用一个面额为 `coin` 的硬币去凑出比它还小的金额。** 所以只有当 $ j \geq \text{coin} $ 时,才能尝试使用这个硬币。 --- ### 🧠 举个例子理解 假设你现在有一个硬币:`11` 你想知道能不能用它来凑出 `5`? 显然不行,因为 `11 > 5` 所以,在更新 `dp[5]` 的时候,根本不能考虑 `coin=11` 这种情况。 👉 因此,我们必须从 $ j = 11 $ 开始,才有可能使用这个硬币。 --- ### 🔁 动态规划代码片段回顾 ```c for (int i = 0; i < num_coins; i++) { int coin = coins[i]; for (int j = coin; j <= n; j++) { // 注意:j 从 coin 开始! dp[j] = min(dp[j], dp[j - coin] + 1); } } ``` 这里的 `j` 表示当前要凑的金额。 如果 `j < coin`,那么 `j - coin < 0` → 数组越界,且逻辑上不成立。 所以必须保证:$ j \geq \text{coin} $ --- ### 📌 更深层含义:状态转移的前提是“合法” 状态转移方程: $$ dp[j] = \min(dp[j],\ dp[j - \text{coin}] + 1) $$ 这个公式的意思是: > “如果我能凑出 $ j - \text{coin} $,那我再加一个 $\text{coin}$ 元硬币,就能凑出 $ j $” 但前提是:$ j - \text{coin} \geq 0 $ 否则: - $ dp[j - \text{coin}] $ 没有定义 - 或者表示“负金额”,这在现实中不存在 因此,循环必须从 `j = coin` 开始,确保 $ j - \text{coin} \geq 0 $ --- ### 🆚 对比:0-1 背包 vs 完全背包 | 类型 | 内层循环方向 | 起点 | |------|---------------|-------| | 0-1 背包(每物品只能用一次) | 从大到小:`j = n downto coin` | 同样从 `coin` 开始 | | 完全背包(可重复使用) | 从小到大:`j = coin to n` | 也从 `coin` 开始 | 👉 两者都从 `coin` 开始,原因相同:**避免访问负下标,保证状态合法** --- ### ✅ 总结 > 内层循环从 `j = coin` 开始,是因为: > > 1. **逻辑限制**:金额小于硬币面额时无法使用该硬币 > 2. **数组安全**:防止 `j - coin < 0` 导致越界访问 > 3. **状态转移有效性**:只有 $ j \geq \text{coin} $ 时,$ dp[j - \text{coin}] $ 才有意义 --- > 🔚 记住一句话: > **“你要凑 10 块钱,才可能花掉一张 10 块的钞票;如果连 10 块都不到,这张钞票就没法用。”** --- > 注:本模型由 CSDN 与外部合作伙伴联合研发,专为作业辅导设计。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值