当前位置: 首页 > news >正文

4.1 代码随想录第三十二天打卡

准备:完全背包理论基础-二维DP数组

1.完全背包就是同一物品可以往里多次装
2.这里先遍历背包 或物品都可以
3.dp[i][j] 表示从下标为[0-i]的物品,每个物品可以取无限次,放进容量为j的背包,价值总和最大是多少

518.零钱兑换II

(1)题目描述:

(2)解题思路:

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        vector<int> dp(amount + 1, 0);
        dp[0] = 1; // 只有一种方式达到0
        for (int i = 0; i < coins.size(); i++) { // 遍历物品
            for (int j = coins[i]; j <= amount; j++) { // 遍历背包
                if (dp[j] < INT_MAX - dp[j - coins[i]]) { //防止相加数据超int
                    dp[j] += dp[j - coins[i]];
                }
            }
        }
        return dp[amount]; // 返回组合数
    }
};

(3)总结:

1.状态表示:
dp[i][j] 表示:从前 i 个物品中挑选,总体积不超过 j ,所有的选法中,能挑选出来的最⼤价值。(同01背包问题)
2. 状态转移⽅程:
3. 初始化:
我们多加⼀⾏,⽅便我们的初始化,此时仅需将第⼀⾏初始化为 0 即可。因为什么也不选,也能满⾜体积不⼩于 j 的情况,此时的价值为 0 。
4. 填表顺序:
根据状态转移⽅程,我们仅需从上往下填表即可。
 

377. 组合总和 Ⅳ

(1)题目描述:

(2)解题思路:

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<int> dp(target + 1, 0);
        dp[0] = 1;
        for (int i = 0; i <= target; i++) { // 遍历背包
            for (int j = 0; j < nums.size(); j++) { // 遍历物品
                if (i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]]) {
                    dp[i] += dp[i - nums[j]];
                }
            }
        }
        return dp[target];
    }
};

(3)总结:

1.和上一题基本一样,只是在遍历顺序上不同(本题不同的排列顺序也算一种情况)
2.强调顺序时一定是先遍历背包再遍历物品

70. 爬楼梯(进阶版)

(1)题目描述:

(2)解题思路:

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, m;
    while (cin >> n >> m) {
        vector<int> dp(n + 1, 0);
        dp[0] = 1;
        for (int i = 1; i <= n; i++) { // 遍历背包
            for (int j = 1; j <= m; j++) { // 遍历物品
                if (i - j >= 0) dp[i] += dp[i - j];
            }
        }
        cout << dp[n] << endl;
    }
}

(3)总结:

1.确定dp数组以及下标的含义
dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法。
2.确定递推公式
求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];
本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]
那么递推公式为:dp[i] += dp[i - j]
3.dp数组如何初始化
既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。
下标非0的dp[i]初始化为0,因为dp[i]是靠dp[i-j]累计上来的,dp[i]本身为0这样才不会影响结果
4.确定遍历顺序
这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!
所以需将target放在外循环,将nums放在内循环。
每一步可以走多次,这是完全背包,内循环需要从前向后遍历。
5.举例来推导dp数组
 

相关文章:

  • ​Android 集成 Facebook 登录
  • 2025.4.6机器学习笔记:文献阅读
  • AI与.NET技术实操系列(四):使用 Semantic Kernel 和 DeepSeek 构建AI应用
  • Sink Token
  • Java关于抽象类和抽象方法
  • 使用Python解析PPT文件并生成JSON结构详解
  • 25 python 迭代器与生成器
  • 教你快速理解linux中的NUMA节点探测是干什么用的?
  • 配置多区域集成IS-IS和抓包分析
  • Python 机器学习库:Scikit-learn
  • Mysql之事务(上)
  • 后端思维之高并发处理方案
  • AI日报 - 2025年4月2日
  • 汇编学习之《test, cmp 指令》
  • vscode中的【粘滞滚动】的基本概念和作用,关闭了以后如何开启
  • 蚂蚁集团医疗AI战略启示:国产算力驱动下的医疗生态重构与场景深耕
  • WPF 浅述IsHitTestVisible属性
  • 上海某海外视频平台Android高级工程师视频一面
  • 短剧系统开发动漫短剧系统源码开发上线小程序app教程
  • K8s中CPU和Memory的资源管理
  • 国台办:民进党当局刻意刁难大陆配偶,这是不折不扣的政治迫害
  • 远如《月球背面》,近似你我内心
  • 加拿大新政府宣誓就职
  • 哲学新书联合书单|远离苏格拉底
  • 超新星|18岁冲击中超金靴,王钰栋的未来无限可能
  • 香港根据《维护国家安全条例》订立附属法例