力扣 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];
    }
};
相关推荐
幺零九零零20 分钟前
【C++】socket套接字编程
linux·服务器·网络·c++
TangKenny22 分钟前
计算网络信号
java·算法·华为
景鹤22 分钟前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie26 分钟前
SCNU习题 总结与复习
算法
捕鲸叉33 分钟前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
Dola_Pan1 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法
yanlou2332 小时前
KMP算法,next数组详解(c++)
开发语言·c++·kmp算法
小林熬夜学编程2 小时前
【Linux系统编程】第四十一弹---线程深度解析:从地址空间到多线程实践
linux·c语言·开发语言·c++·算法
阿洵Rain2 小时前
【C++】哈希
数据结构·c++·算法·list·哈希算法
姜西西_2 小时前
动态规划 之 斐波那契数列模型 算法专题
算法·动态规划