322 零钱兑换
步骤1:定义状态数组
定义 dp[i]
表示组成金额 i
所需的最少硬币数。
步骤2:状态转移方程
对于每个硬币 coin
和金额 i
,若 coin ≤ i
,则尝试用该硬币更新状态
逻辑解释:若用 coin
面额硬币,则当前最少硬币数为 dp[i - coin] + 1
(加1表示使用这枚硬币)
步骤3:遍历顺序
采用外层遍历硬币,内层遍历金额的正序填充方式(完全背包特性)
遍历顺序说明:完全背包问题中,每个硬币可以重复使用,因此内层循环正序更新。
步骤4:处理结果
最终检查目标金额是否可达
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
if (amount == 0) return 0;
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for (auto coin : coins) {
for (int i = coin; i <= amount; ++i) {
if (dp[i - coin] != INT_MAX) {
dp[i] = min(dp[i - coin] + 1, dp[i]);
}
}
}
return dp[amount] == INT_MAX ? -1 : dp[amount];
}
};