力扣 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];
    }
};
相关推荐
沫璃染墨9 分钟前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Session
linux·服务器·c++·tcp/ip·ubuntu·http·交互
nm_zfyjt12 分钟前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
xiaoye-duck1 小时前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(下):流式响应实现和测试
开发语言·网络·c++·语言模型
w_zero_one1 小时前
算法--构造
java·数据结构·算法
其实防守也摸鱼2 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
旖旎夜光2 小时前
【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针
开发语言·c++·笔记·学习
小超人诞生日记3 小时前
C++ 智能指针的使用及其原理详解
c++·算法
akinggw4 小时前
libagentcore - 一个基于c++的AI多agent系统升级到2.0版本
开发语言·jvm·c++
繁星蓝雨5 小时前
C++设计原理———多重继承(虚基类、菱形继承、委托、重命名、基类和成员初始化)
c++·委托·多重继承·mi·显式初始化列·虚基类·对象布局