【力扣一刷】代码随想录day44(动态规划part6 - 背包问题专题: 完全背包理论基础、卡码网52、518. 零钱兑换 II、377. 组合总和 Ⅳ )

devtools/2024/9/25 23:24:16/

【完全背包理论基础】

与01背包问题的区别:

1、物品的可取次数:完全背包和01背包问题唯一不同的地方就是,01背包问题的每种物品只能取0次或1次,而完全背包问题的每种物品可以取无限次。

2、遍历滚动数组的顺序:01背包问题每件物品最多取一次,前面取了后面就不能取,所以要逆向遍历书包容量。而完全背包问题可以取无限次,因此是正向遍历,即使前面的书包容量放过物品 i 也可以。遍历第 i 个物品,书包容量为 j 时,不取第 i 个物品,则直接返回旧值dp[ j ],取第 i 个物品时,最大容量为 dp[j - weights[i]] + values[i],其中dp[j - weights[i]]的意思是留足够的空间给需要取的第 i 个物品,再从 0 ~ i 个(包括第 i 个)物品中取,背包容量为j - weights[i]能装下的最大容量。

【52. 携带研究材料(第七期模拟笔试)】

区别:遍历书包容量的时候,是正向遍历。

import java.util.*;public class Main{public static void main (String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int V = sc.nextInt();int[] weights = new int[N];int[] values = new int[N];for (int i = 0; i < N; i++){weights[i] = sc.nextInt();values[i] = sc.nextInt();}int[] dp = new int[V+1];for (int i = 0; i < N; i++){for (int j = weights[i]; j < V + 1; j++){dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);}}System.out.println(dp[V]);}
}
  • 时间复杂度:O(N×V),N是物品的种类数,V是容量的大小
  • 空间复杂度:O(V)

【518. 零钱兑换 II】中等题

难点:

1、属于完全背包问题,需要正序遍历背包容量,从刚好能装第i个物品的背包容量开始遍历,即初始值 j = coins[i]。

2、要求的是恰好把背包装满的方案数,是放与不放的方案数的叠加,即dp[j] += dp[j - coins[i]];。

3、求的是组合数,外层for遍历的是物品,内层for遍历的是背包容量。

class Solution {public int change(int amount, int[] coins) {int dp[] = new int[amount + 1];dp[0] = 1; // 与题意理解不一样,但是设置amount=0,无论coins输入什么,输出都是1for (int i = 0; i < coins.length; i++){for (int j = coins[i]; j < amount + 1; j++){ // 完全背包:正序遍历dp[j] += dp[j - coins[i]]; // 求的是恰好装满背包的方案数,放和不放的叠加}}return dp[amount];}
}
  • 时间复杂度:O(M×N),M是硬币的种类数,N是amount的数值大小
  • 空间复杂度:O(N)

【377. 组合总和 Ⅳ】中等题

技巧:

1、判断:背包问题 or 完全背包问题?

  • 01背包问题 - 逆序遍历背包容量(不可重复取)
  • 完全背包问题 - 正序遍历背包容量(可重复取)

2、判断:组合数 or 排列数?

  • 求组合数 - 外层for循环遍历物品,内层for遍历背包容量。(物品顺序固定)
  • 求排列数 - 外层for遍历背包容量,内层for循环遍历物品。(物品顺序可变)

3、判断:求最大容量 or 方案数?

  • 求最大容量 dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);  (求最大)
  • 求方案数 dp[j] += dp[j-nums[i]]; (求叠加)

分析:

1、数组中的元素可以重复取,无限次数,属于完全背包问题,正序遍历背包容量

2、顺序不同的序列被视作不同的组合,相当于求的是排列数外层for循环遍历背包容量

3、求的是方案数,使用叠加的公式,记得设置初始值 dp[0] = 1,否则后面全是0。

class Solution {public int combinationSum4(int[] nums, int target) {int[] dp = new int[target + 1];dp[0] = 1;// 求排列数for (int i = 0; i < target + 1; i++){ // 外层for正序遍历书包容量for (int j = 0; j < nums.length; j++){ // 内层for遍历物品if (i >= nums[j]) dp[i] += dp[i - nums[j]]; // 书包容量足够(>=)的情况下才能考虑取}}return dp[target];}
}
  • 时间复杂度:O(M×N),M是target,N是nums数组的元素个数
  • 空间复杂度:O(M)

http://www.ppmy.cn/devtools/35058.html

相关文章

人工智能原理第十三章课后习题(仅供参考)

13.1 举例说明什么是数据&#xff0c;信息与知识&#xff0c;以及他们之间的关系 数据&#xff1a;是客观世界的计量及其最简单的表征方式&#xff0c;数据表现为事实、信号或者符号。 信息&#xff1a;是赋予含义的数据&#xff0c;可通过一些手段进行传播。 知识&#xff1a;…

【Web】CTFSHOW 新手杯 题解

目录 easy_eval 剪刀石头布 baby_pickle repairman easy_eval 用script标签来绕过 剪刀石头布 需要赢100轮&#x1f914; 右键查看源码拿到提示 一眼session反序列化 打PHP_SESSION_UPLOAD_PROGRESS 脚本 import requestsp1 a|O:4:"Game":1:{s:3:"log…

【Vue3源码学习】— CH3.3 renderer.ts详解

renderer.ts详解 1.概念理解1.1 主要功能1.2 核心函数1.3 流程说明1.4 学习 render.ts2.createRenderer2.1 源码解析2.2 代码解释2.2.1 泛型参数2.2.2 函数参数2.3 使用示例2.4 总结1.概念理解 1.1 主要功能 功能描述渲染和更新 DOM渲染器的核心职责是将 VNode 树转换成 DOM 树…

第二十六章 版本管理 - GIT

文章目录 一、版本管理二、版本管理工具的常见概念三、git的安装和使用1. 安装2. 基础使用流程&#xff08;本地仓库&#xff09;3. 辅助命令4. 远程仓库操作5. git的分支6. 注意&#xff1a;7. 团队协作时分支处理8. 补充&#xff1a; 一、版本管理 什么是版本&#xff1a;一…

Docker私有仓库与Harbor部署使用

目录 一、本地私有仓库 1. 下载registry镜像 2. 在daemon.json文件中添加私有镜像仓库地址 ​编辑 3. 运行registry容器 4. Docker容器的重启策略如下 5. 为镜像打标签 6. 上传到私有仓库 7. 列出私有仓库的所有镜像 8. 列出私有仓库的centos镜像有哪些tag 9. 先删…

hadoop学习---基于hive的数仓搭建增量信息拉链表的实现

拉链表就是SCD2&#xff0c;它的优点是即满足了反应数据的历史状态&#xff0c;又能在最大程度上节省存储。 拉链表的实现需要在原始字段基础上增加两个新字段&#xff1a; start_time(表示该条记录的生命周期开始时间——周期快照时的状态)end_time(该条记录的生命周期结束时…

PyTorch中 DataLoader 和 TensorDataset 的详细解析

DataLoader 和 TensorDataset PyTorch DataLoader 和 TensorDataset 的详细解析DataLoader 介绍DataLoader 的核心功能 TensorDataset 介绍TensorDataset 的核心功能 使用 DataLoader 和 TensorDataset 加载数据关键内容解析 结论 PyTorch DataLoader 和 TensorDataset 的详细解…