算法训练营Day42(背包问题)

news2024/11/20 14:22:37

基础

非竞赛只需要搞懂0-1背包和完全背包

0-1背包基础

0-1背包是完全背包和多重背包的基础

n个物品,每个物品一个,每个物品有自己的重量和价值,,一个背包能装m物品,问最多装多少物品。

暴力解法,n个物品,2^n

dp数组:

可以二维,也可以优化成一维

二维

dp[i][j]:  0-i的0物品任选一个放到背包j中,价值总和最大是多少

递推公式

dp[i][j]

不放物品i,,物品是 i 背包为j,最大价值,

        dp[i-1][j]:不放物品i的最大价值。

放物品i: 物品为i-1{代表从0到i-1中选物品,所以物品i已经被放到背包}          

        dp[i-1]dp[j-weight[i]+value[i] 

        {i-1代表0到i个物品,去掉i, 

         j-weight[i]{代表物品i放入背包,剩下的重量为这个}

        value[i]   :物品的价值

        dp[i-1][j-weight[i]]代表放入物品i,剩下物品的最大价值

        两者相加就是当前背包的最大价值。

物品只有放与不放,所以递推公式:

        dp[i][j] = Math.max(dp[i-1][j],Math.max(dp[i-1][j-weight[i]+value[i]))

初始化

dp[i][j]由上面{dp[i-1][j]}推除,或者左上角推出

还是初始化第一列和第一行

背包容量为0的时候,什么也不能放了,物品0到i都是初始化为0

第一行,这个要初始化的时候要看物品0的重量,如果为3

那么3 4这两个要初始化成value[0]

也就是weight[0]到i初始化成value[0]

遍历顺序

先遍历哪个都可以,因为从左上和上遍历,这两个都可以通过递推公式遍历完

代码

public class BagProblem {
    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){

        // 创建dp数组
        int goods = weight.length;  // 获取物品的数量
        int[][] dp = new int[goods][bagSize + 1];

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

        // 填充dp数组
        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 < goods; i++) {
            for (int j = 0; j <= bagSize; j++) {
                System.out.print(dp[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}

0-1背包-一维数组

压缩原理

因为每一层都是由上一层得到的,所以可以先拷贝到,通过滚动数组的形式实现原地修改!

dp数组含义

dp[j]       :  容量为j时,背包最大价值为dp[j]

递推公式

不放物品i,因为这个数组是上一层拷贝下来的,上一层比如,物品1,那么这一层是物品2,直接拷贝下来,是不包含物品2的,

所以不妨物品i   :容量为j时,背包的最大价值就是dp[j]  {也就是抛去物品i的最大价值}

放物品i时:  

        容量肯定要编程j-weight[j]的,现在放物品i,当前逻辑就要加上i的价值value[i]

        {{{其实从最开始,初始化,后面价值的总和都是加这个value[i]得到的

        所以最大价值时dp[j-weight[i]] 

所以递推公式为:

        dp[j] = Math.max(dp[j],dp[j-weight]+value[i]){物理上就是数组当前位置和左面-weight位置}

初始化

容量为0 那么价值肯定0

所以初始化,dp[0]=0;

非0 的话,会被覆盖,默认为0就可

遍历顺序

现在数组是上一层的结果,想要倒叙遍历得到才是正常的计算

代码

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

    public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){
        int wLen = weight.length;
        //定义dp数组:dp[j]表示背包容量为j时,能获得的最大价值
        int[] dp = new int[bagWeight + 1];
        //遍历顺序:先遍历物品,再遍历背包容量
        for (int i = 0; i < wLen; i++){
            for (int j = bagWeight; j >= weight[i]; j--){
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
        //打印dp数组
        for (int j = 0; j <= bagWeight; j++){
            System.out.print(dp[j] + " ");
        }
    }

416. 分割等和子集

416. 分割等和子集 - 力扣(LeetCode)

class Solution {
    public boolean canPartition(int[] nums) {
        if(nums == null || nums.length == 0) return false;
        int sum = 0;
        for(int num : nums) {
            sum += num;
        }
   

        if(sum%2!=0) return false;
        int target = sum/2;
        //dp数组 :含义:容量为j时,最大价值为dp[j]
        int [] dp = new int[target+1];
        //初始化
        //默认为0即可

        //遍历顺序
        //先遍历物品
        for(int i = 0;i<nums.length;i++){
            for(int j = target;j>=nums[i];j--){
                //递推公式
                dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
        return dp[target] == target;
    }
    
}

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

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

相关文章

循环中的continue和break | python

1 continue continue关键字用于:中断本次循环&#xff0c;直接进入下一次循环 continue可以用于:for循环和while循环&#xff0c;效果一致 上侧代码: 在循环内&#xff0c;遇到continue就结束当次循环&#xff0c;进行下一次所以&#xff0c;语句2是不会执行的。 1.1 应用场…

网点分散难管理?组网是物流企业的正解!

物流企业服务网点分散、难以管理是企业面临的一个问题&#xff0c;而组网是解决这一问题的正解。通过建立统一的网络&#xff0c;物流企业可以实现更好的资源管理和信息流动&#xff0c;从而提高运营效率和服务水平&#xff0c;实现企业的可持续发展。 随着物流业务的不断拓展…

pycharm导入etree报Cannot find reference ‘etree‘ in ‘__init__.py‘ more... (Ctrl+F1)

问题 发现 from lxml import etree的时候&#xff0c;etree报错了。提示Cannot find reference etree in __init__.py more... (CtrlF1)。 解决办法 后面发现是pycharm自己的BUG&#xff0c;所以写了新的写法

黑马苍穹外卖学习Day2

文章目录 员工管理模块实现新增员工需求设计分析代码开发功能测试代码完善 员工分页查询需求分析与设计代码开发功能测试代码完善 启用禁用员工账号需求分析和设计代码开发功能测试 编辑员工需求分析代码开发 导入分类模块功能代码需求分析设计 员工管理模块实现 新增员工 需…

小程序基础学习(组件化)

&#xff08;一&#xff09;创建 找到components文件夹下面创建新的文件夹 然后再文件夹内创建component格式的文件 创建后这样 我创建的是my-info的文件夹以及my-info的components文件&#xff0c;跟着普通的页面一样 &#xff08;二&#xff09; 注册组件 找到你需要使用组…

刚开始学习 c++ 要注意哪些方面?

刚开始学习 c 要注意哪些方面&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&…

API获取商品详情电商补单及价格监控调用api

很多电商系统&#xff0c;如返利系统、ERP、OMS软件等&#xff0c;需要通过商品API接口获取商品详情信息&#xff0c;来满足业务场景需要。具体包括&#xff1a;商品的标题、价格、SKU、主图、评价等维度信息 获取key和密钥 返回数据&#xff1a; {"item": {"…

MacOS安装Miniforge、Tensorflow、Jupyter Lab等(2024年最新)

大家好&#xff0c;我是邵奈一&#xff0c;一个不务正业的程序猿、正儿八经的斜杠青年。 1、世人称我为&#xff1a;被代码耽误的诗人、没天赋的书法家、五音不全的歌手、专业跑龙套演员、不合格的运动员… 2、这几年&#xff0c;我整理了很多IT技术相关的教程给大家&#xff0…

查看Linux磁盘空间

(1)、该命令会列出当前系统所有挂载的文件系统以及它们的使用情况&#xff0c;包括总容量、已用空间、可用空间、使用百分比等信息 df -h如果查看某一个文件夹的,可以 df -h folderName (2)、计算指定目录下所有文件和子目录所占用的磁盘空间大小&#xff0c;并以人类可读的格…

创建型模式 | 工厂模式

文章目录 一、简单工厂1.1、原理1.2、核心角色1.3、UML类图1.4、代码实现1.5、总结 二、工厂模式2.1、原理2.2、关键角色2.3、代码实现2.4、总结 三、抽象工厂模式3.1、原理3.2、关键角色3.3、UML类图3.4、工厂模式与抽象工厂模式的区别 前言 工厂模式是最常用的设计模式之一&a…

ROS---激光雷达的使用

ROS—激光雷达的使用 激光雷达是现今机器人尤其是无人车领域及最重要、最关键也是最常见的传感器之一&#xff0c;是机器人感知外界的一种重要手段。本文将介绍在ROS下使用激光雷达传感器&#xff0c;我们选用的激光雷达型号为思岚A1。 使用流程如下: 硬件准备&#xff1b;软…

C++——简介、Hello World、变量常量、数据类型

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

idea编译报错(Maven项目)

idea编译报错 找不到符号 第一步&#xff1a;开启注解处理器 第二步&#xff1a;清理MVN&#xff0c;package并重新编译 第三步&#xff1a;重新导入项目&#xff1a;

本地开发环境请求服务器接口跨域的问题(vue的问题)

上面的这个报错大家都不会陌生&#xff0c;报错是说没有访问权限&#xff08;跨域问题&#xff09;。本地开发项目请求服务器接口的时候&#xff0c;因为客户端的同源策略&#xff0c;导致了跨域的问题。下面先演示一个没有配置允许本地跨域的的情况&#xff1a; 可以看到&…

【亲测有效】Win11 卸载MySQL5.7以及安装MySQL8.0.35

目录 一、卸载原来本地的mysql5.7 1.mysql服务部分 1.1停止mysql服务 1.2删除mysql服务 2.卸载 MySQL程序 3.残余文件的清理 3.1删除mysql安装的目录 3.2删除mysql数据存放的目录 3.3删除mysql自定义目录 4.清理注册表 5.删除环境变量配置 二、安装mysql8.0.35 1.…

Explain详解与索引最佳实践

Mysql安装文档参考&#xff1a;https://blog.csdn.net/yougoule/article/details/56680952 Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句&#xff0c;分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字&#xff0c;MySQL 会在查询…

全网第一篇教你怎么总结多线程知识

于「全景图」&#xff0c;我之前也有一直在构建&#xff0c;可是因为知识储备不够&#xff0c;确实很难构建出来。稍微了解过并发领域知识的人都知道&#xff0c;里面的知识点、概念多而散&#xff1a;线程安全、锁、同步、异步、阻塞、非阻塞、死锁、队列(为什么并发要跟队列扯…

2024年云服务器配置推荐,看看哪家便宜?

作为多年站长使市面上大多数的云厂商的云服务器都使用过&#xff0c;很多特价云服务器都是新用户专享的&#xff0c;本文有老用户特价云服务器&#xff0c;阿腾云atengyun.com有多个网站、小程序等&#xff0c;国内头部云厂商阿里云、腾讯云、华为云、UCloud、京东云都有用过&a…

Backtrader 文档学习-Strategy with Signals

Backtrader 文档学习-Strategy with Signals backtrader可以不通过重写策略的方式触发交易&#xff0c;尽管重写策略是首选通用的方式。 下面介绍通过使用信号也是可以实现交易触发的。 1.定义signal import backtrader as btdata bt.feeds.OneOfTheFeeds(datanamemydatana…

微信公众号使用后端代码接入开发指南

1. 部署到服务器一套后端服务 要求&#xff1a;外界通过get请求可以访问到该服务&#xff0c;并且该地址只返回文本&#xff1a;hello, this is handle view&#xff0c;这就是下面这段代码的意思 这段代码的意思就是服务匹配到/wx的get请求&#xff0c;返回文本hello, this …