React+TS+css in js 练习

今天分享的内容是动态规划的经典问题--0-1 背包问题

0-1背包问题的描述如下:给定一组物品,每种物品都有自己的重量和价值,背包的总容量是固定的。我们需要从这些物品中挑选一部分,使得背包内物品的总价值最大,同时不超过背包的总容量。
举个例子:假设这组物品的质量分别是:

const weight = [2, 2, 6, 4, 3];

背包总容量为 9,请问将这些物品装入背包,最多能装多少,分别是哪些?

思路分析

之前用回溯算法解决过这个问题,回溯算法有其自身的局限性--指数级别的复杂度。那这篇文章就和上篇文章一样,用动态规划的思路把 0-1 背包问题重新解决一遍

回溯算法的思路是,每种可能都去尝试,即遍历所有的可能,找到最优解。而动态规划不会傻傻地遍历所有的可能性,而是会去掉重复的路径,在剩下的路径下继续探索

背包的总容量是 9,那么不看具体的物品重量,放入背包的重量的可能性一共有 9 种,动态规划将会使计算范围框定在这 9 种范围之内,并且相同重量的物品组合,只保留其中一种。这样下来,动态规划的复杂度就是 n*m 了,n 是物品的种类,m 是背包的总容量

看不明白?没关系,看看下面的过程分析就懂啦

过程分析

image.png

weight = [2, 2, 6, 4, 3];

代码的实现就是填满上面的表格。行表示,该行的物品不放的重量种类;列表示背包中物品重量之和
上面第一个行填了两个 true,第一个 true 表示不放 1 号物品时,背包的总重量是 0kg;第二个 true 表示放 1 号物品时,背包的总重量是 2kg
继续填第二行

image.png

weight = [2, 2, 6, 4, 3];

共有 3 个 true, 第一个 true 和 第二个 true 表示不放入 2 号物品时,背包的重量可能性--有 0kg2kg 两种可能性;第三个 true 表示,同时放 1 号物品和 2 号物品的情况。

其实,大家仔细想想,如果只放 2 号物品,不放 1 号物品时,背包的重量是多少?也是 2kg,所以第二个 true 也表示只放 2 号物品,不放 1 号物品的情况。这里动态规划将两个 2kg 的情况合并成一种情况。

以至于 1 号和 2 号物品的放与不放有 2^2 种情况,但是组合成的重量却只有 3 种情况. 这就是动态规划提升性能的关键

继续往下看

image.png

weight = [2, 2, 6, 4, 3];

第三行共有 5 个 true,前 3 个 true 直接看成是不放 3 号物品时,背包重量的可能性。后面两个 true,一个是 6kg,是只放 3 号物品的情况;另一个是 8kg,可以看成是放 1 号和 3 号物品的情况,也可以看成是 2 号和 3 号物品的情况。

3 种物品共有 2^3 情况,但是动态规划将其合并成 5 种情况。

true 的填写是有规律的,首先填写不放该行物品的情况,即直接照抄上一行的内容,然后从前往后依次对每个 true 的重量加上自身重量,比如第 3 行的第 4 个 true,就是第一个 true 的 0kg 加上 6kg 得到的。第 3 行的第 5 个 true ,是第二个 true 的 2kg 加上 6kg 得到的。再往后相加的话就超过 9kg 了,就停止相加。

大家可以试着推推第 4 行的内容


第 4 行:

image.png

weight = [2, 2, 6, 4, 3];

第 5 行:

image.png

weight = [2, 2, 6, 4, 3];

可以看到第 5 行的最后一格是 true,也就说明,物品的组合中,是可以将背包填满的。所以背包可以装入的最大重量是 9kg,问题解决!

代码实现

const weight = [1, 2, 2, 6, 5, 8];

const findWeight = (weight) => {
  const store = Array(weight.length)
    .fill(1)
    .map(() => Array(packageWeight + 1).fill(false));
  
  store[0][0] = true;
  
  store[0][weight[0]] = true;

  for (let i = 1; i < store.length; i++) {
    // 不放第i个物品
    for (let j = 0; j <= packageWeight; j++) {
      if (store[i - 1][j]) store[i][j] = true;
    }

    // 放第i个物品
    for (let j = 0; j <= packageWeight - weight[i]; j++) {
      if (store[i - 1][j]) store[i][j + weight[i]] = true;
    }
  }

  for (let i = packageWeight; i >= 0; i--) {
    if (store[weight.length - 1][i]) {
      console.log("the max weight is ", i);
      break;
    }
  }
}
  1. 定义一个数组weight,表示物品的重量。变量packageWeight,表示背包的容量。接着实现了一个名为findWeight的函数,该函数接受一个参数weight,即物品重量的集合

在findWeight函数中,首先创建一个二维数组store,用来表示上面过程分析的表格,表格的内容初始化为 false。store 的行和列含义也和上面表格一致。在遍历 store 之前,先初始化第一行的内容,即放与不放 0 号物品的两种情况。

遍历 store 数组,从第二行开始,也就是 i==1。每一行先考虑不放第 i 个物品。然后再计算放入第 i 个物品的时候,这一行的内容有什么变化。

遍历完所有的行,store 数组中最后一行的最后一个 true 所表示的重量,就是我们要的答案啦

执行代码

findWeight(weight);
// the max weight is  9

这是 store 的内容:

image.png

换个数据试试:

const weight = [2, 2, 6, 4, 4];
findWeight(weight);
// the max weight is  8

这是 store 中的内容情况:

image.png

遗留的问题

按照上面的代码只是知道了最多能装多少,但不知道装了哪些东西,你可以根据最后生成的store内容判断放入了哪些东西吗?在之后的文章中,大家可以看到对这个问题的解答

总结

这篇文章讲了如何用动态规划来解决 0-1 背包问题,其中有解题的思路分析,还有具体的过程分析,每个过程都有图片,很清晰了。相信大家对着图片多看几遍,就知道动态规划是怎么解决问题的了。最后还有 JS 代码实现,大家可以 copy 到本地跑一跑,这样会更清楚

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/926800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

刷题日常(找到字符串中所有字母异位词,​ 和为 K 的子数组​,​ 滑动窗口最大值​,全排列)

找到字符串中所有字母异位词 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 题目分析&#xff1a; 1.将p里面的字符先丢进一个hash1中&#xff0c;只需要在S字符里面找到多少个和他相同的has…

《C++ Primer Plus》学习笔记|第8章 函数探幽 (24-11-30更新)

文章目录 8.1 内联函数8.2 引用变量8.2.1 创建引用变量8.2.2 将引用用作函数参数8.2.3 引用的属性和特别之处特点1&#xff1a;在计算过程中&#xff0c;传入的形参的值也被改变了。特点2&#xff1a;使用引用的函数参数只接受变量&#xff0c;而不接受变量与数值的运算左值引用…

[2024年1月28日]第15届蓝桥杯青少组stema选拔赛C++中高级(第二子卷、编程题(1))

参考程序&#xff1a; #include <iostream> #include <algorithm> // 用于 std::sortusing namespace std;int main() {int a, b, c;cin >> a >> b >> c;// 将三个数放入一个数组中int arr[3] {a, b, c};// 对数组进行排序sort(arr, arr 3);…

基于hexo框架的博客搭建流程

这篇博文讲一讲hexo博客的搭建及文章管理&#xff0c;也算是我对于暑假的一个交代 &#xff01;&#xff01;&#xff01;注意&#xff1a;下面的操作是基于你已经安装了node.js和git的前提下进行的&#xff0c;并且拥有github账号 创建一个blog目录 在磁盘任意位置创建一个…

基于Java Springboot传统戏曲推广微信小程序

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 微信…

数据结构--树二叉树顺序结构存储的二叉树(堆)

前言 前面我们学习了顺序表、链表、栈和队列&#xff0c;这些都是线性的数据结构。今天我们要来学习一种非线性的数据结构——树。 树的概念及结构 树的概念 树是一种非线性的数据结构&#xff0c;是由n&#xff08;n≥0&#xff09;个有效结点组成的一个具有层次关系的集合…

网络安全运行与维护 加固练习题

1. 提交用户密码的最小长度要求。 输入代码: cat /etc/pam.d/common-password 提交答案: flag{20} 2.提交iptables配置以允许10.0.0.0/24网段访问22端口的命令。 输入代码: iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 22 -j ACCEPT 提交答案: flag{iptables -A I…

【汇编语言】call 和 ret 指令(三) —— 深度解析汇编语言中的批量数据传递与寄存器冲突

文章目录 前言1. 批量数据的传递1.1 存在的问题1.2 如何解决这个问题1.3 示例演示1.3.1 问题说明1.3.2 程序实现 2. 寄存器冲突问题的引入2.1 问题引入2.2 分析与解决问题2.2.1 字符串定义方式2.2.2 分析子程序功能2.2.3 得到子程序代码 2.3 子程序的应用2.3.1 示例12.3.2 示例…

Java 泛型详细解析

泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair&#xff0c;它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型&#xff0c;比如下面所示&#xff0c;就指定了实际类型为 LocalDate…

Python语法基础(四)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 高阶函数之map 高阶函数就是说&#xff0c;A函数作为B函数的参数&#xff0c;B函数就是高阶函数 map&#xff1a;映射 map(func,iterable) 这个是map的基本语法&#xff0c;…

【JavaEE初阶】应是天仙狂醉,乱把白云揉碎 - (重点)线程

本篇博客给大家带来的是线程的知识点, 由于内容较多分几天来写. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ⭐欢迎大家点赞 评论 收藏 分享 ❤❤❤ 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 1. 认识线程 1.1 概念 )1 …

构建鸿蒙5.0应用(一)

准备工作 1、开发工具 开发工具使用华为官方推荐的IDE&#xff1a;DevEco Studio &#xff0c;为鸿蒙应用开发提供了最全面的官方支持&#xff0c;包括最新的 SDK、API 和功能。 2、编译工具 开发鸿蒙应用需要安装Nodejs环境&#xff0c;为打包编译鸿蒙应用提供支持&#x…

【Linux】匿名管道通信场景——进程池

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

FUSU: 多源多时相土地利用变化分割数据集

FUSU是首个针对细粒度城市语义理解的多时态、多源地类变化分割数据集&#xff0c;其提供高分辨率双时态图像和每月时序观测&#xff0c;支持对城市动态变化的高频率监测。FUSU-Net是统一的时序架构&#xff0c;可同时进行变化检测和分割任务。结合光学和SAR数据&#xff0c;通过…

LLM学习笔记(13)分词器 tokenizer

由于神经网络模型不能直接处理文本&#xff0c;因此我们需要先将文本转换为数字&#xff0c;这个过程被称为编码 (Encoding)&#xff0c;其包含两个步骤&#xff1a; 使用分词器 (tokenizer) 将文本按词、子词、字符切分为 tokens&#xff1b;将所有的 token 映射到对应的 tok…

Unity中让光点跟图片填充区的末尾一起移动

一、实现效果展示 想要实现的效果如下,就是要让白色光点图片跟随绿色圆形图片填充区末尾一起移动。 二、代码如下: using UnityEngine; using System.Collections; using UnityEngine.UI; using DG.Tweening;public class IconCircle : MonoBehaviour {public float ti…

给定一个整数可能为正,0,负数,统计这个数据的位数.

题目描述 给定一个整数可能为正,0,负数,统计这个数据的位数. 例如1234567输出7位; -12345678输出8位;0输出1位 代码实现 int main() { long long m; long long n; scanf("%lld",&n); mn; int count0;//位数 do { count; n/10;//舍弃个位 }while(n!0); printf(&…

LLamafactory API部署与使用异步方式 API 调用优化大模型推理效率

文章目录 背景介绍第三方大模型API 介绍LLamafactory 部署API大模型 API 调用工具类项目开源 背景介绍 第三方大模型API 目前&#xff0c;市面上有许多第三方大模型 API 服务提供商&#xff0c;通过 API 接口向用户提供多样化的服务。这些平台不仅能提供更多类别和类型的模型…

【关闭or开启电脑自带的数字键盘】

目录 一、按数字键盘左上角的按键【NumLK Scroll】 二、修改注册表中数字键盘对应的数值【InitialKeyboardIndicators】 1、步骤&#xff1a; 2、知识点&#xff1a; 一、按数字键盘左上角的按键【NumLK Scroll】 这是最简单快捷的方法。 关闭后若想开启&#xff0c;再按一…

【FAQ】使用Node.js 镜像 构建本地项目

在nodejs官方并没有提供使用node.js构建本地项目的方法&#xff0c;但是通过阅读官方文档&#xff0c;可以发现&#xff0c;官方在包管理器界面提供了如下语句 所以node.js容器是可以执行语句的 下面通过docker 的 -w 、-v 参数设置容器工作目录和目录映射&#xff08;实现本…