【01背包理论】01背包问题dp[i][j](二维数组) <动态规划板子>

news2025/1/21 17:57:40

【01背包理论】01背包问题 dp[i][j]

有 n 件物品和一个最多能背重量为 w 的背包。
第 i 件物品的重量是 weight[i],得到的价值是 value[i] 。
每件物品只有一个,求解将哪些物品装入背包里物品价值总和最大。

题解

动态规划

  • 确定 dp 数组以及下标的含义
    dp[i][j] 表示从下标为 [0-i] 的物品里任意取,放进容量为 j 的背包,价值总和最大是多少。

  • 确定递推公式
    有两个方向推出来 dp[i][j]

    • 不放物品 i:由 dp[i - 1][j] 推出,即背包容量为 j,里面不放物品 i 的最大价值,此时 dp[i][j] 就是 dp[i - 1][j] 。(其实就是当物品 i 的重量大于背包 j 的重量时,物品 i 无法放进背包中,所以背包内的价值依然和前面相同)
    • 放物品 i:由 dp[i - 1][j - weight[i]] 推出,dp[i - 1][j - weight[i]] 是背包容量为 j - weight[i] 的时候不放物品 i 的最大价值,那么 dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。
      所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
  • dp 数组如何初始化
    从 dp[i][j] 的定义出发,如果背包容量 j 为 0 的话,即 dp[i][0],无论是选取哪些物品,背包价值总和一定为0。
    在这里插入图片描述
    状态转移方程 可以看出 i 是由 i-1 推导出来,那么 i 为 0 的时候就一定要初始化,dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

    • 当 j < weight[0] 的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。
    • 当 j >= weight[0] 时,dp[0][j] 应该是 value[0],因为背包容量放足够放编号0物品。
  • 确定遍历顺序
    dp[i][j] 都是从其上方和左上方推导而来,有两个遍历的维度:物品与背包重量

  • 举例推导 dp 数组(打印 dp 数组)

public class Solution {
    public static void main(String[] args) {
        int[] weight = {1,3,4};
        int[] value = {15,20,30};
        int bagSize = 4;
        testWeightBagProblem(weight,value,bagSize);
    }

    /**
     * 动态规划获得结果
     * @param weight  物品的重量
     * @param value   物品的价值
     * @param bagSize 背包的容量
     */
    public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){

        // 获取物品的数量
        int goodsNum = weight.length;
        //定义dp数组:dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少
        int[][] dp = new int[goodsNum][bagSize + 1];

        // 初始化dp数组,其中默认的值就是0
        for (int i = weight[0]; i <= bagSize; i++) {
            dp[0][i] = value[0];
        }

//        //遍历,先遍历背包,再遍历物品(竖着遍历)
//        for(int j = 1; j <= bagSize; j++) { // 遍历背包容量
//            for(int i = 1; i < weight.length; i++) { // 遍历物品

        //遍历,先遍历物品,然后遍历背包重量(横着遍历)
        for (int i = 1; i < weight.length; i++) {   // 遍历物品
            for (int j = 1; j <= bagSize; j++) {    // 遍历背包容量
                if (j < weight[i]) {
                    /**
                     * 当前背包的容量都没有当前物品i大的时候,是不放物品i的
                     * 那么前 i-1个物品能放下的最大价值就是当前情况的最大价值
                     */
                    dp[i][j] = dp[i-1][j];
                } else {
                    /**
                     * 当前背包的容量可以放下物品i
                     * 那么此时分两种情况:
                     *  1、不放物品i
                     *  2、放物品i
                     * 比较这两种情况下,哪种背包中物品的最大价值最大
                     */
                    dp[i][j] = Math.max(dp[i-1][j] , dp[i-1][j-weight[i]] + value[i]);
                }
            }
        }

        // 打印 dp数组
        for (int i = 0; i < goodsNum; i++) {
            for (int j = 0; j <= bagSize; j++) {
                System.out.print(dp[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Docker安装和部署RabbitMQ

&#x1f680; 1 拉取RabbitMQ Docker镜像 首先&#xff0c;使用Docker命令从Docker Hub拉取RabbitMQ官方镜像。打开终端并运行以下命令&#xff1a; docker pull rabbitmq&#x1f680; 2 创建RabbitMQ容器 一旦镜像下载完成&#xff0c;使用以下命令创建RabbitMQ容器&…

报错合集 ing - net::ERR_ABORTED 500 (Internal Server Error)

报错&#xff1a;net::ERR_ABORTED 500 (Internal Server Error) 根据提示找到对应文件 解决&#xff1a;检查代码&#xff0c;根据高亮颜色判断&#xff0c;发现箭头函数漏了一个>。 报错&#xff1a;Uncaught TypeError: Assignment to constant variable. &#xff08…

【负载均衡】常见的负载均衡策略有哪些?

文章目录 前言负载均衡分类常见负载均衡策略小结 前言 负载均衡策略是实现负载均衡器的关键&#xff0c;而负载均衡器又是分布式系统中不可或缺的重要组件。使用它有助于提高系统的整体性能、可用性、可靠性和安全性&#xff0c;同时支持系统的扩展和故障容忍性。对于处理大量…

新建工程——第一个S32DS工程

之前的"测试开发板"章节 测试开发板——第一个AutoSAR程序,使用了一个 demo 工程,不管是裸机程序还是 AutoSAR 程序,那都是别人已经创建好的工程。本节来介绍如何来创建自己的工程,本节介绍如何创建一个 S32DS 的工程,点亮开发板上的 LED 我们从官方提供的例程…

C++(20):多重继承与虚继承

多重继承 是指从多个直接基类中产生派生类的能力。多重继承的派生类继承了所有父类的属性。 多重继承 在派生类的派生列表中可以包含多个基类&#xff1a; class Bear : public zooAnimal { class Panda : public Bear, public Endangered{/* ...*/};每个基类包含一个可选的…

Android 大图显示优化方案-加载Gif 自定义解码器

基于Glide做了图片显示的优化&#xff0c;尤其是加载Gif图的优化&#xff0c;原生Glide加载Gif图性能较低。在原生基础上做了自定义解码器的优化&#xff0c;提升Glide性能 Glide加载大图和Gif 尤其是列表存在gif时&#xff0c;会有明显卡顿&#xff0c;cpu和内存占用较高&…

Android学习之路(13) Handler详解

1. 简介 Handler是一套 Android 消息传递机制,主要用于线程间通信。 用最简单的话描述&#xff1a; handler其实就是主线程在起了一个子线程&#xff0c;子线程运行并生成Message&#xff0c;Looper获取message并传递给Handler&#xff0c;Handler逐个获取子线程中的Message.…

RT-Thread 中断管理学习(二)

中断的底半处理 RTT不对中断服务程序所需要的处理时间做任何假设、限制&#xff0c;但如图其它实时操作系统或非实时操作系统一样&#xff0c;用户需要保证所有的中断服务程序在尽可能短的时间内完成&#xff08;中断服务程序在系统中相当于拥有最高的优先级&#xff0c;会抢占…

论文研读-SIMD系列-利用BMI指令进行选择下推

利用位操作指令BMI在列存中进行选择下推 Selection Pushdown in Column Stores using Bit Manipulation Instructions 列存能够提供高效的压缩能力&#xff0c;所以当前分析型数据库系统都基于列存储。然而&#xff0c;查询处理时&#xff0c;压缩会面临解码速率的挑战。以往研…

亚马逊产品流量上不去怎么办?亚马逊产品流量入口有哪些?

众所周知流量对于跨境卖家们是很重要的&#xff0c;这影响了你产品的曝光度和转化率&#xff0c;那么如果亚马逊产品流量上不去怎么办&#xff0c;亚马逊产品流量入口有哪些&#xff1f; 亚马逊产品流量上不去怎么办&#xff1f; 1、优化产品标题和关键词 产品标题和关键词是…

mojo初体验

目录标题 mojo初体验试用地址变量定义参数可变性和所有权Structures后续 mojo初体验 试用地址 https://www.modular.com/get-started 与python基础语法很相似。 变量定义 let定义不可变变量var定义可变变量 参数可变性和所有权 下面是一个基本的函数&#xff1a; fn add…

第一章 计算机概述

1.冯诺依曼结构&#xff1a; 计算机由运算器、控制器、存储器、输入设备、输出设备五大部件组成 运算器和控制器称为CPU&#xff1b;CPU和存储器称为计算机主机&#xff1b;其余输入、输出设备、外存储器称为计算机外部设备采用二进制表示数据和指令 指令由操作码&#xff08;…

AJAX学习笔记1发送Get请求

传统请求有哪些方式,及缺点 传统请求有哪些? 1.直接在浏览器地址栏上输入URL. 2.点击超连接. <a href"/上下文/请求地址">超链接请求</a> ---->相对路径 <a href"http://www.baidu.com">超链接请求</a> ---->绝对路…

【Java 基础篇】Java StringBuffer详解:更高效的字符串处理

在Java编程中&#xff0c;字符串是一个常见的数据类型&#xff0c;用于存储文本信息。然而&#xff0c;与字符串相关的操作可能会导致性能问题&#xff0c;因为字符串是不可变的&#xff0c;每次对字符串进行操作都会创建一个新的字符串对象。为了解决这个问题&#xff0c;Java…

Windows命令行初步:更改配色、提示符以及编码方式

文章目录 启动和退出窗口标题和提示符命令行颜色更改编码 启动和退出 按下winR&#xff0c;调出运行窗口&#xff0c;输入cmd就可以进入命令行了。在Win10以前的系统种&#xff0c;如果在命令行中再输入一个cmd&#xff0c;就会再打开一个命令行。但最近的Win11版本中&#xf…

[管理与领导-66]:IT基层管理者 - 辅助技能 - 4- 乌卡时代(VUCA )的团队管理思维方式的转变

目录 一、乌卡时代人与公司的关系的转变 二、乌卡时代管理方式的转变 三、乌卡时代的管理与传统时代的管理比较 四、乌卡时代管理者的挑战 五、乌卡时代如何做好管理 六、个人能力要求 一、乌卡时代人与公司的关系的转变 在乌卡时代&#xff08;指虚拟办公、远程工作等数…

实景三维数字孪生系统(实景三维电子沙盘)

一、概况 实景三维数字孪生系统是一种基于虚拟现实技术的系统&#xff0c;紧紧围绕应急处置的核心业务&#xff0c;通过将真实世界的物体、场景和过程数字化&#xff0c;创建出一个与真实世界相对应的虚拟模型。它可以模拟真实世界中的各种情境和操作&#xff0c;使用户能够在虚…

PYTHON知识点学习-函数调用中returnprint

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是Aileen★。希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由 Aileen_0v0★ 原创 CSDN首发&#x1f412; 如需转载还请通知⚠ &am…

1779_树莓派小车电机驱动软件实现

全部学习汇总&#xff1a; GitHub - GreyZhang/little_bits_of_raspberry_pi: my hacking trip about raspberry pi. 前几天看了树莓派小车实现的硬件相关部件梳理视频&#xff0c;今天看了一段树莓派小车的电机驱动软件实现。 视频非常短&#xff0c;从里面能够提取出来的我感…

图上简单路径问题——转化为圆方树问题:abc318_g

https://atcoder.jp/contests/abc318/tasks/abc318_g 对原图建圆方树后&#xff0c;任意两点间的简单路径必然为其树上路径上方点对应其边双的点。 然后判断A&#xff0c;C路径上的方点是否会有B 圆方树&#xff1a; void dfs(int x) {dfn[x]low[x]tot; z.push(x); for(int …