力扣 322. 零钱兑换

题目来源:https://leetcode.cn/problems/coin-change/description/

C++题解(来源代码随想录):题目中说每种硬币的数量是无限的,可以看出是典型的完全背包问题。动规五部曲分析如下:

  1. 确定dp数组以及下标的含义。dpj:凑足总额为j所需钱币的最少个数为dpj
  2. 确定递推公式。凑足总额为j - coinsi的最少个数为dpj - coins\[i],那么只需要加上一个钱币coinsi即dpj - coins\[i] + 1就是dpj。递推公式:dpj = min(dpj - coins\[i] + 1, dpj);
  3. dp数组如何初始化。首先凑足总金额为0所需钱币的个数一定是0,那么dp0 = 0; 其他下标对应的数值呢?考虑到递推公式的特性,dpj必须初始化为一个最大的数,否则就会在min(dpj - coins\[i] + 1, dpj)比较的过程中被初始值覆盖。所以下标非0的元素都是应该是最大值。
  4. 确定遍历顺序。本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数
  5. 举例推导dp数组
cpp 复制代码
class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); i++) { // 遍历物品
            for (int j = coins[i]; j <= amount; j++) { // 遍历背包
                if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过,不跳过+1会超出int范围。
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if (dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};
相关推荐
凡人叶枫10 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
noipp10 小时前
推荐题目:洛谷 P10907 [蓝桥杯 2024 国 B] 蚂蚁开会
c语言·c++·算法·编程·洛谷
学逆向的11 小时前
C++纯虚函数
开发语言·c++·网络安全
程序员二叉11 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
青山木11 小时前
Hot 100 --- 轮转数组
java·数据结构·算法
徐小夕12 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
凡人叶枫12 小时前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
北域码匠13 小时前
SHA-1算法:安全哈希原理与应用解析
算法·c#·哈希算法
坚果派·白晓明13 小时前
【鸿蒙PC】SDL3 移植:AtomCode Skills 4 步速通多媒体库适配
c++·华为·ai编程·harmonyos·atomcode·c/c++三方库
手写码匠14 小时前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc