力扣 322. 零钱兑换

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

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

  1. 确定dp数组以及下标的含义。dp[j]:凑足总额为j所需钱币的最少个数为dp[j]
  2. 确定递推公式。凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j]。递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
  3. dp数组如何初始化。首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0; 其他下标对应的数值呢?考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。所以下标非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];
    }
};
相关推荐
云边有个稻草人2 小时前
【刷题】Day4--密码检查
开发语言·数据结构·笔记·算法
ujn201612222 小时前
2640. Find the Score of All Prefixes of an Array
leetcode
苦瓜汤补钙3 小时前
论文阅读:3D Gaussian Splatting for Real-Time Radiance Field Rendering
论文阅读·人工智能·算法·3d
图像处理大大大大大牛啊3 小时前
使用mingw64 编译 QT开发流程
开发语言·c++·qt·命令模式
LNTON羚通3 小时前
明烟明火检测算法、烟火检测、森林防火检测
大数据·网络·人工智能·算法·音视频
爱上杨小厨3 小时前
MFC实现对话框与控件的自适应调节
c++·mfc
Bill664 小时前
MFC之CString类及其成员函数用法详解
c++·mfc
MogulNemenis4 小时前
力扣100题——技巧
算法·leetcode
每天瞎忙的农民工4 小时前
PHP常用的几种算法
算法·php
Flame_Cyclone4 小时前
编写XBOX控制器实现鼠标键盘输入
c++·windows·win32·xbox·控制器模拟键盘鼠标