动态规划 Leetcode 322 零钱兑换

零钱兑换

Leetcode 322

学习记录自代码随想录

要点:1.背包容量为amount,物品重量为coinsi,物品价值为1;

2.因为求最小值递推公式为 d p j = m i n ( d p j , d p j − c o i n s \[ i ] + 1 ) dpj = min(dpj, dpj-coins\[i]+1) dpj=min(dpj,dpj−coins\[i]+1);

3.dp数组初始化,因为是min所以dp0 = 0, 其余值初始化为UINT_MAX;

4.在迭代判断时要跳过dpj-coins\[i] == INT_MAX这种情况,并且此时也没有比较的必要,但是不能不加这个条件,因为UINT_MAX+1会回滚到0导致迭代出错;

c 复制代码
unsigned int min(unsigned int a, unsigned int b){
    return a < b ? a : b;
}

int coinChange(int* coins, int coinsSize, int amount) {

    if(amount == 0) return 0;
    
    // int sum = 0;
    // for(int i = 0; i < coinsSize; i++) sum += coins[i];

    // 1.dp[j]代表凑成总金额为j(背包容量)时所需的最少的硬币个数, 物品重量为coins[i], 物品价值为1
    unsigned int dp[amount+1];
    memset(dp, UINT_MAX, sizeof(dp));
    // memset(dp, 0, sizeof(dp));
    
    // 2.递推公式:dp[j] = max(dp[j], dp[j-coins[i]] + 1)
    // 3.dp数组初始化为UINT_MAX
    dp[0] = 0;
    // 4.遍历顺序,每个物品可以无限拿,所以先物品再背包, 均为正向遍历
    for(int i = 0; i < coinsSize; i++){
        for(int j = coins[i]; j < amount+1; j++){
            // 如果dp[j-coins[i]]为UINT_MAX,则UINT_MAX+1会重新变为0导致整体迭代会出错需要注意!
            if(dp[j-coins[i]] != UINT_MAX){  
                dp[j] = min(dp[j], dp[j-coins[i]] + 1);
            }
        }
    }
    // 5.举例推导dp数组
    if(dp[amount]) return dp[amount];
    return -1;

}
相关推荐
Full Stack Developme4 小时前
Java LRU 与 LFU 算法及应用
java·开发语言·算法
Jerry5 小时前
LeetCode 707. 设计链表
算法
C语言小火车5 小时前
C++ 堆排序深度精讲:基于完全二叉树的选择排序进化,最坏情况 O(n log n) 的稳定王者
开发语言·c++·算法·排序算法·堆排序
kebidaixu5 小时前
两轮BMS AFE SH367306 I2C 读写时序
算法
智能排队系统_头部供应商5 小时前
RK3588边缘网关改造银行排队系统实战
算法
Fabarta6 小时前
从 0 实现 ChatGPT 风格的流式对话 UI
算法·架构
手写码匠6 小时前
手写 AI 上下文压缩系统:从零实现 Prompt 压缩与选择性上下文管理
人工智能·深度学习·算法·aigc
EAI-Robotics7 小时前
机器人操作鲁棒性:当机械手遇上真实世界的不确定性
人工智能·算法·机器人
Tairitsu_H7 小时前
[LC优选算法#17] 链表 | 合并 K 个升序链表 | K个⼀组翻转链表
数据结构·算法·链表