【动态规划算法(dp算法)】之背包问题

文章目录

      • 背包问题
        • 动规五部曲
        • 一、0-1背包问题 :限制物品不可重复 (要么不选 要么选一个)
        • 二、完全背包问题:不限制重复(要么不选 要么可以多选)(完全背包可以转化为0-1背包问题)
      • 动态规划:01背包 二维dp数组
      • 动态规划:01背包滚动数组
      • 动规五部曲分析如下:
      • 动态规划代码

背包问题

在这里插入图片描述

动规五部曲

其中最主要的就是前两个步骤

  • 确定dp数组以及下标的含义
  • 确定递推公式
  • dp数组如何初始化
  • 遍历顺序
  • 出结论,写代码
一、0-1背包问题 :限制物品不可重复 (要么不选 要么选一个)
二、完全背包问题:不限制重复(要么不选 要么可以多选)(完全背包可以转化为0-1背包问题)

下面讲的是0-1背包问题:

其中:

  • i,表示物品;j表示背包容量;
  • w[] 数组表示物品重量的集合;
  • v[] 数组表示物品价值的集合;
  • v[][]表示装入背包的最大价值集合;

(1)找w[i]和j的关系

v[i][0]=v[0][j]=0,表示第一列和第一行最大价值都是0;

  • 1.w[i]>j,表示当前准备新增物品的质量要是大于背包的容量,v[i][j] =v[i-1][j],该位置的最大价值就是把该列上一行的数据赋给它;如第二次音响进来的最大价值情况;v[i-1][j]上一个单元格装入的最大价值;
  • 2.j>=w[i],表示背包的容量要是大于等于当前要新增物品的质量;

(2) 则装入的最大价值策略为v[i][j] = max { v[i-1][j], v[i] + v[i-1][j-w[i]] }
v[i] 当前商品的价值;
j-w[i] 装入当前物品后,背包剩余的容量大小;

(3) v[i] + v[i-1][j-w[i]]表示:装入当前物品的价值 + 剩余容量可装入的最大价值
最后比较 两个最大价值,取max

eg:总w=4;电脑w=3装入后的价值2000 + 剩余w=1只可装一个吉他价值1500=3500 > 上一个单元格装入的最大价值3000
所以选择这个装配方式;

上面讲的很清楚了 看一下具体的实现

那么可以有两个方向推出来dp[i][j]:

1.不放物品idp[i][j]=dp[i - 1][j]
w[i]>j,表示:当前准备新增物品的质量要是大于背包的容量,v[i][j] =v[i-1][j]
就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。

2.放物品i
表示背包的容量要是大于等于当前要新增物品的质量;

  • dp[i - 1][j - weight[i]]推出,
    dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候 不放物品i(所以是i-1)的最大价值
  • value[i]+dp[i - 1][j - weight[i]]
    表示:装入当前物品的价值 + 剩余容量可装入的最大价值

所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

动态规划:01背包 二维dp数组

动规五部曲分析一波

  1. 确定dp数组以及下标的含义
- 对于背包问题,有一种写法, 是使用二维数组,即dp[i][j] 表示从下标为[0,i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
- w[i] 表示第i个物品的重量;
- v[i] 表示第i个物品的价值;

要时刻记着这个dp数组的含义,下面的一些步骤都围绕这dp数组的含义进行的,如果哪里看懵了,就来回顾一下i代表什么,j又代表什么。

  1. 确定递推公式
再回顾一下dp [i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
# 那么可以有两个方向推出来dp[i][j]:
##1.不放物品i:dp[i][j]=dp[i - 1][j]。
------w[i]>j,表示当前准备新增物品的质量要是大于背包的容量,v[i][j] =v[i-1][j],就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。
##2.放物品i:表示背包的容量要是大于等于当前要新增物品的质量;#  dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候 不放物品i(所以是i-1)的最大价值,#  value[i]+dp[i - 1][j - weight[i]]  表示:装入当前物品的价值 + 剩余容量可装入的最大价值所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

动态规划:01背包滚动数组

读到这里估计大家都忘了 dp[i][j]里的ij表达的是什么了,i是物品,j是背包容量。

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

动规五部曲分析如下:

  1. 确定dp数组的定义

    在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]

  2. 一维dp数组的递推公式

  • dp[j]可以通过dp[j - weight[i]]推导出来
    dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。
    dp[j - weight[i]] + value[i] 表示:容量为 j-物品i重量的背包的价值 加上 物品i的价值。
    (就是容量为j的背包,放入物品i了之后的价值再加上物品i的价值)
  • 此时dp[j]有两个选择
    一个是取自己dp[j] 相当于二维dp数组中的dp[i-1][j],即不放物品i;
    一个是取dp[j - weight[i]] + value[i],即放物品i,指定是取最大的,毕竟是求最大价值,
  • 所以递归公式为:
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  1. 一维dp数组如何初始化

dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j],那么背包容量为0所背的物品的最大价值就是0。

所以dp[0]=0

假设物品价值都是大于0的,所以dp数组初始化的时候,都初始为0就可以了。

Arrays.fill(dp,0);
  1. 遍历顺序从后向前

​ 还是先遍历物品,然后再遍历背包容量

for(int i = 0; i < v.length; i++) { // 遍历物品for(int j = weight; j >= w[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - w[i]] + v[i]);}
}

动态规划代码

  1. 代码
public static void main(String[] args) {int[] v = {15, 20, 30};int[] w = {1, 3, 4};int weight = 4;int[] dp = new int[weight + 1];Arrays.fill(dp, 0);//i是物品 j是背包重量 所以物品重量是w[i]int res=dp[0];for (int i = 0; i < v.length; i++) {for (int j = weight; j >= w[i]; j--) {dp[j]=Math.max(dp[j],dp[j-w[i]]+v[i]);res=Math.max(res,dp[j]);}}System.out.println(res);}
public static void main(String[] args) {int[] value = new int[]{1500, 2000, 3000};//表示物品的价值int[] weight = {1, 4, 3};//表示物品的重量int w = 4;//背包的容量int n = value.length;//物品的个数//创建一个二维数组 表 n+1行:有一行是0行;w+1列:有一列是0列int[][] dp = new int[n + 1][w + 1];  //n+1就是列长 w+1就是行长//1.初始化第一行第一列for (int i = 0; i < w + 1; i++) {dp[0][i] = 0;//第一行为0}for (int i = 0; i < n + 1; i++) {dp[i][0] = 0;//第一列为0}int res=dp[0][0];//2.判断物品重量w[i] 和背包容量的关系for (int i = 1; i < dp.length; i++) {//从第一行for (int j = 1; j < dp[0].length; j++) {//第一列开始if (weight[i-1] > j) {//i-1是因为我们从1开始的dp[i][j] = dp[i - 1][j];} else {dp[i][j] = Math.max(dp[i - 1][j], (value[i-1] + dp[i - 1][j - weight[i-1]]));//value[i-1] //是因为我们的i是从1开始的 所以-1//weight[i-1]}res=Math.max(res,dp[i][j]);}}
//        3.打印这个最大价值表for (int i = 0; i <dp.length ; i++) {for (int j = 0; j <dp[0].length; j++) {System.out.print(dp[i][j]+"\t");}System.out.println();}System.out.println("最大价值为:"+res);}
}

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

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

相关文章

使用OpenCV4实现工业缺陷检测的六种方法

目录 1 机器视觉2 缺陷检测3 工业上常见缺陷检测方法 1 机器视觉 机器视觉是使用各种工业相机&#xff0c;结合传感器跟电气信号实现替代传统人工&#xff0c;完成对象识别、计数、测量、缺陷检测、引导定位与抓取等任务。其中工业品的缺陷检测极大的依赖人工完成&#xff0c;…

企业数据治理:(1)概述

目录 确定数据治理的规范与标准 设立与数据治理规范和标准相匹配的组织架构 明确数据治理的范围 制定切实可行的治理目标与实施计划 数据治理是企业IT系统建设当中的重要组成部分&#xff0c;是一种综合性的方法和实践&#xff0c;目的在确保数据的完整性、准确性和一致性。…

部署tomcat单机多实例,keepalived+mysql的互为主从高可用,mysql+keepalived高可用

部署tomcat单机多实例 在Tomcat中部署单机多实例是一种常见的做法&#xff0c;它允许您在同一台服务器上运行多个独立的Tomcat实例&#xff0c;每个实例都有自己的配置、日志和应用程序。 安装jdk环境 首先配置java环境 [roottomcat ~]# tar xf jdk-8u211-linux-x64.tar.gz…

nodejs+vue+ElementUi会员制停车场车位系统

总之&#xff0c;智能停车系统使停车场管理工作规范化&#xff0c;系统化&#xff0c;程序化&#xff0c;避免停车场管理的随意性&#xff0c;提高信息处理的速度和准确性&#xff0c;能够及时、准确、有效的查询和修改停车场情况。 三、任务&#xff1a;小组任务和个人任务 智…

旅游海报图怎么做二维码展示?扫码即可查看图片

现在旅游攻略的海报可以做成二维码印刷在宣传单单页或者分享给用户来了解目的地的实际情况&#xff0c;出行路线、宣传海报等。用户只需要扫描二维码就可以查看内容&#xff0c;更加的方便省劲&#xff0c;那么旅游海报的图片二维码制作的技巧有哪些呢&#xff1f;使用图片二维…

2015年第四届数学建模国际赛小美赛A题飞机上的细长座椅解题全过程文档及程序

2015年第四届数学建模国际赛小美赛 A题 飞机上的细长座椅 原题再现&#xff1a; 航空公司座位是指在旅途中乘客可以乘坐的座位。一些航空公司现在推出了新的经济舱“超薄”座位。这些座椅除了重量较轻外&#xff0c;理论上还允许航空公司在不显著影响乘客舒适度的情况下增加运…

STL中优先队列的模拟实现与仿函数的介绍

文章目录 仿函数优先队列的模拟实现 仿函数 上回我们说到&#xff0c;优先队列的实现需要用到仿函数的特性 让我们再回到这里 这里我们发现他传入的用于比较的东西竟然是一个类模板&#xff0c;而不是我们所见到的函数 我们可以先创建一个类&#xff0c;用于比较大小 struc…

陶建辉在 CIAS 2023 谈“新能源汽车的数字化”

近年&#xff0c;中国的新能源汽车发展迅猛&#xff0c;在全球竞争中表现出色&#xff0c;已经连续 8 年保持全球销量第一。在新兴技术的推动下&#xff0c;新能源汽车的数字化转型也正在加速进行&#xff0c;从汽车制造到能源利用、人机交互&#xff0c;各个环节都在进行数字化…

RobotMaster学习——工序导入,参数设置,轨迹生成

目录 引出1.导入工序2.修改刀具其他刀具参数 3.进行工序分配4.设置TCP5.设置工作站6.工序整体导入配置7.进行计算 总结 引出 RobotMaster的操作流程&#xff0c;从导入工序到生产轨迹。 1.导入工序 2.修改刀具 要选择第七把刀具 其他刀具参数 第一把刀具 第二把刀具 第三把刀…

C语言的分支和循环语句

各位少年&#xff0c;今天和大家分享的是分支语句循环体语句&#xff0c;C语言是结构体的程序设计语言&#xff0c;这里的结构指的是&#xff08;顺序结构&#xff09;&#xff08;选择结构&#xff09;&#xff08;循环结构&#xff09;C语言是能够实现这三种结构的&#xff0…

作为程序员,你知道 Notion 吗?

Notion 是一款极其出色的个人笔记软件&#xff0c;它将“万物皆对象”的思维运用到笔记中&#xff0c;让使用者可以天马行空地去创造、拖拽、链接。也适用于康奈尔笔记法哦。 不知大家会不会有如下烦恼&#xff1a; 1.当你下载了许多 APP&#xff0c;也注册了许多账号&#x…

Prometheus-JVM

一. JVM监控 通过 jmx_exporter 启动端口来实现JVM的监控 Github Kubernetes Deployment Java 服务&#xff0c;修改 wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.19.0/jmx_prometheus_javaagent-0.19.0.jar# 编写配置文件&#xff0…

Nacos单机安装

采用的版本是Nacos Release 2.3.0 (Nov 30, 2023) alibaba/nacos GitHub 依赖于jdk&#xff0c;要先安装好jdk1.8。 修改配置 下载解压后&#xff0c;修改配置文件&#xff1a;conf/application.properties。 nacos.core.auth.plugin.nacos.token.secret.key 官方文档Na…

【SVN】centos7搭建svn--亲测能通

centos7.6搭建svn 1 知识小课堂1.1 CentOS1.2 SVN 2 搭建过程2.1 前期准备2.2 通过yum命令安装svnserve2.3 创建版本库目录2.4 创建svn版本库2.5 配置修改2.5 防火墙配置2.6 启动或关闭svn服务器2.6.1 进程守护2.6.2 检测svn端口3690是否已经监听&#xff1a;2.6.3 关闭SVN 2.7…

随机森林 2(决策树)

通过 随机森林 1 的介绍&#xff0c;相信大家对随机森林都有了一个初步的认知&#xff0c;知道了随机和森林分别指的是什么&#xff0c;以及决策树根据什么选择内部节点。本文将会从森林深入到树&#xff0c;去看一下决策树是如何构建的。网上很多文章都讲了决策树如何构建&…

Linux常用基本命令(三)

一、显示命令 1. cat 通式&#xff1a;cat 选项 文件名 只能看普通的文本文件 缺点&#xff1a;如果内容过多会显示不全 选项效果-n显示行号包括空行-b跳过空白行编号-s讲所有的连续的多个空行替换为一个空行&#xff08;压缩成一个空行&#xff09;-A显示隐藏字符 三个标准文件…

【XR806开发板试用】通过http请求从心知天气网获取天气预报信息

1. 开发环境搭建 本次评测开发环境搭建在windows11的WSL2的Ubuntu20.04中&#xff0c;关于windows安装WSL2可以参考文章: Windows下安装Linux(Ubuntu20.04)子系统&#xff08;WSL&#xff09; (1) 在WSL的Ubuntu20.04下安装必要的工具的. 安装git: sudo apt-get install git …

【UML】第9篇 类图(概念、作用和抽象类)(1/3)

目录 一、类图的概念 二、类图的主要作用 三、类图的构成 3.1 类的名称 3.2 抽象类&#xff08;Abstract Class&#xff09; 一、类图的概念 类图是UML模型中静态视图。它用来描述系统中的有意义的概念&#xff0c;包括具体的概念、抽象的概念、实现方面的概念等。静态视…

服务器数据恢复-误操作导致xfs分区数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌OceanStorT系列某型号存储MD1200磁盘柜&#xff0c;组建的raid5磁盘阵列。上层分配了1个lun&#xff0c;安装的linux操作系统&#xff0c;划分两个分区&#xff0c;分区一通过lvm进行扩容&#xff0c;分区二格式化为xfs文件系统。 服务器…

深入了解C编译管道

文章目录 引言1. 预处理阶段2. 编译阶段3. 汇编阶段4. 链接阶段5.流程图结论 引言 C编译管道是软件开发中至关重要的工具&#xff0c;它负责将C语言源代码转换为可执行的机器代码。理解C编译管道的工作原理有助于提高代码的可读性、可维护性&#xff0c;并有助于优化生成的可执…