动态规划算法之背包问题详细解读(附带Java代码解读)
动态规划中的背包问题(Knapsack Problem)是经典问题之一,通常用来解决选择一组物品放入背包使得背包的价值最大化的问题。根据问题条件的不同,背包问题有很多种变体,如0-1背包问题、完全背包问题、多重背包问题等。这里,我们详细介绍最经典的0-1背包问题,并提供代码的详细解读。
1. 0-1背包问题简介
在0-1背包问题中,有一个容量为 C
的背包和 n
件物品。每件物品有两个属性:重量 w[i]
和 价值 v[i]
。目标是选择若干件物品放入背包,使得总重量不超过 C
,并且背包中物品的总价值最大化。
问题的约束:
- 每件物品要么选择(放入背包),要么不选择,因此称为 0-1 背包问题。
- 背包的总重量不能超过
C
。 - 要最大化背包中物品的总价值。
2. 动态规划的思路
动态规划适用于背包问题,因为它具有最优子结构和重叠子问题的性质。解决这个问题的核心在于:针对每一个物品,都有两种选择——要么放进背包,要么不放进背包。
状态定义
定义 dp[i][j]
表示前 i
件物品放入容量为 j
的背包时所能获得的最大总价值。
状态转移方程
对于每件物品 i
:
- 如果不将第
i
件物品放入背包,则最大价值就是dp[i-1][j]
,即前i-1
件物品的最大价值。 - 如果将第
i
件物品放入背包,则最大价值为dp[i-1][j-w[i]] + v[i]
,即前i-1
件物品在剩余容量j-w[i]
时的最大价值加上当前物品的价值v[i]
。
综合起来,状态转移方程为:
dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]+v[i])
初始条件
当背包容量为0时,无论选哪件物品,最大价值都是0,即 dp[i][0] = 0
。
3. Java代码实现
public class Knapsack {public static void main(String[] args) {// 定义物品的重量和价值int[] weights = {2, 3, 4, 5}; // 每个物品的重量int[] values = {3, 4, 5, 6}; // 每个物品的价值int capacity = 8; // 背包容量int n = weights.length; // 物品数量// 计算并输出背包的最大价值System.out.println("Maximum value in Knapsack = " + knapsack(weights, values, n, capacity));}// 动态规划方法解决0-1背包问题public static int knapsack(int[] weights, int[] values, int n, int capacity) {// 定义DP数组:dp[i][j] 表示前 i 件物品在容量为 j 时的最大价值int[][] dp = new int[n + 1][capacity + 1];// 填充DP表for (int i = 1; i <= n; i++) {for (int j = 1; j <= capacity; j++) {if (weights[i - 1] <= j) { // 当前物品可以放入背包dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);} else { // 当前物品无法放入背包dp[i][j] = dp[i - 1][j];}}}// 返回最后一个格子的值,即最大价值return dp[n][capacity];}
}
4. 详细解释代码
4.1 输入和输出
在 main
方法中,定义了物品的重量数组 weights[]
、价值数组 values[]
,以及背包的总容量 capacity
和物品数量 n
。然后调用 knapsack()
方法来计算背包中可以获得的最大价值。
4.2 knapsack()
函数详解
public static int knapsack(int[] weights, int[] values, int n, int capacity) {// 定义DP数组:dp[i][j] 表示前 i 件物品在容量为 j 时的最大价值int[][] dp = new int[n + 1][capacity + 1];
首先,定义了二维数组 dp[][]
,其中 dp[i][j]
表示前 i
件物品在背包容量为 j
时能够获得的最大总价值。数组的大小为 [n+1][capacity+1]
,因为我们需要处理物品数量从0到n、容量从0到capacity的所有情况。
4.3 初始化和状态转移
for (int i = 1; i <= n; i++) {for (int j = 1; j <= capacity; j++) {if (weights[i - 1] <= j) {dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);} else {dp[i][j] = dp[i - 1][j];}}
}
接下来,用两个嵌套的 for
循环遍历物品和背包容量,进行状态转移:
- 外层循环
i
遍历每一件物品。 - 内层循环
j
遍历背包的每个可能容量。
对于每个物品 i
:
- 如果该物品的重量
weights[i-1]
小于或等于当前容量j
,可以选择放入背包或不放入背包,选择价值最大的方案。这就是通过状态转移方程dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weights[i-1]] + values[i-1])
计算出的。 - 如果该物品的重量
weights[i-1]
超过当前容量j
,则无法将其放入背包,此时只能继承前i-1
件物品的最大价值,即dp[i][j] = dp[i-1][j]
。
4.4 返回最大价值
return dp[n][capacity];
循环结束后,dp[n][capacity]
就是前 n
件物品在背包容量为 capacity
时能够获得的最大价值,因此返回该值。
5. 复杂度分析
- 时间复杂度:
O(n * capacity)
,因为我们需要填充一个大小为n * capacity
的表。 - 空间复杂度:
O(n * capacity)
,因为我们使用了二维数组dp[][]
存储中间结果。
6. 空间优化
在上述实现中,我们用了二维数组 dp[][]
来存储所有状态。但实际上,在每一行 i
的状态转移时,只依赖于上一行 i-1
的值。因此,我们可以将二维数组压缩为一维数组,从而降低空间复杂度到 O(capacity)
。
public static int knapsackOptimized(int[] weights, int[] values, int n, int capacity) {int[] dp = new int[capacity + 1];for (int i = 1; i <= n; i++) {// 从大到小遍历容量,保证每个物品只被计算一次for (int j = capacity; j >= weights[i - 1]; j--) {dp[j] = Math.max(dp[j], dp[j - weights[i - 1]] + values[i - 1]);}}return dp[capacity];
}
关键点:
- 在每次迭代中,从容量
capacity
开始递减遍历,确保每个物品只更新一次。这种写法防止了在同一轮次中更新状态值时物品被重复选择。
7. 总结
0-1背包问题通过动态规划求解,有明确的状态转移方程。使用二维DP表来记录每个物品在不同容量下的最大价值,最终得到最优解。通过压缩空间,可以进一步优化到一维DP表。
相关文章:
动态规划算法之背包问题详细解读(附带Java代码解读)
动态规划中的背包问题(Knapsack Problem)是经典问题之一,通常用来解决选择一组物品放入背包使得背包的价值最大化的问题。根据问题条件的不同,背包问题有很多种变体,如0-1背包问题、完全背包问题、多重背包问题等。这里…...

Vue3+TypeScript二次封装axios
安装如下 npm install axios 第一步:创建config配置文件,用于存放请求后端的ip地址,用于后期打包后便于修改ip地址。 注:typescript要求参数要有类型。(ES6 定义对象 属性 类型 修改的是属性的值) inte…...

华为 HCIP-Datacom H12-821 题库 (16)
有需要题库的可以加下方Q群 V群进行学习交流 1. OSPF 邻居关系建立出现故障,通过 display ospf error 命令来检查,输出结果如图所示,根据图中内容分析,邻居建立失败的原因可能是以下哪一项? A、Process ID 不一致 B、…...

【论文分享精炼版】 sNPU: Trusted Execution Environments on Integrated NPUs
今天在COMPASS分享了之前写的一个博客,做了进一步的提炼总结,大家可以看看原文~ 今天分享的论文《sNPU: Trusted Execution Environments on Integrated NPUs》来自2024年ISCA,共同一作为Erhu Feng以及Dahu Feng。并且, 这两位作…...
MyBatis 入门之动态 SQL
文章目录 一、什么是动态 SQL二、MyBatis 中的动态 SQL 标签三、动态 SQL 的使用示例四、总结 在 Java 开发中,MyBatis 是一个非常流行的持久层框架,它提供了强大的 SQL 映射功能和动态 SQL 支持。动态 SQL 可以根据不同的条件动态地生成 SQL 语句&#…...
软工大二学生待办事项:
该文章会常年更新!坚持! 2024.9.10 学习打包部署 记录睡眠 开始刷一个算法 巩固Git版本控制工具的使用 巩固利用Idea使用版本管理工具,SQl编写 抓紧时间了解公司营业执照 坚持到周末再打瓦!...
MongoDB延迟查询
在 MongoDB 中,查看副本集成员之间的副本延迟可以通过以下步骤进行: 使用 rs.status() 命令: 这个命令提供了副本集的详细状态信息,包括每个成员的延迟情况。在 MongoDB shell 中,你可以执行以下命令: rs.s…...
python如何获取html中的所有链接
在Python中,获取HTML页面中的所有链接通常可以通过使用第三方库如BeautifulSoup或lxml来完成。这里,我将提供一个使用BeautifulSoup库的示例,因为它简单易用且功能强大。 首先,你需要安装BeautifulSoup和requests库(如…...
79-java static修饰的类能不能被继承
Java中的类可以被final关键字修饰,表示这个类不能被继承。如果一个类被final修饰,那么这个类不能被继承,也就是说,final类不能被继承。 另一方面,static关键字可以用来修饰内部类,这样的内部类是静态内部类…...

MacOS wine中文乱码问题
安装wine 1、brew update 执行失败,提示安装如下 2、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow 3、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow 3、brew update 4、brew in…...

基于Springboot的鲜花销售网站的设计与实现
项目描述 这是一款基于Springboot的鲜花销售网站的系统 模块描述 鲜花销售系统 1、用户 登录 在线注册 浏览商品 鲜花搜索 订购商品 查询商品详情 水果分类查看 水果加购物车 下单结算 填写收货地址 2、管理员 登录 用户管理 商品管理 订单管理 账户管理 截图...

安卓玩机工具-----适合安卓机型的“搞机工具箱” 功能齐全 玩机推荐
搞机工具箱最新版是一款相当出色的电脑端手机工具箱软件,搞机工具箱正式版功能强劲,可以帮助用户不需要root就能够直接对手机进行调节,方便对手机进行更加全面的掌控,搞机工具箱便捷好用,只需要根据文字提示及自己的需…...
数据分析-17-时间序列分析的平稳性检验
1 什么是时间序列 时间序列是一组按时间顺序排列的数据点的集合,通常以固定的时间间隔进行观测。这些数据点可以是按小时、天、月甚至年进行采样的。时间序列在许多领域中都有广泛应用,例如金融、经济学、气象学和工程等。 时间序列的分析可以帮助我们理解和预测未来的趋势和…...
Unity3D Android多渠道极速打包方案详解
在移动应用开发过程中,特别是在使用Unity3D进行Android游戏或应用开发时,多渠道打包是一个常见且重要的需求。不同的渠道(如Google Play、华为应用市场、小米应用商店等)可能需要不同的配置和包名,手动进行这些操作既耗…...
数据库中的主键和外键分别是什么意思?
让我们来聊聊数据库设计中非常重要的两个概念——主键(Primary Key)和外键(Foreign Key)。这两个概念对于保证数据的一致性和完整性至关重要。 主键(Primary Key) 主键是一个表中的一个或一组字段&#x…...
HTML5中`<ul>`标签深入全面解析
在HTML5的广阔天地里,<ul>标签作为无序列表的代言人,扮演着举足轻重的角色。它不仅能够整洁地罗列信息,还通过丰富的属性和样式选项,为网页设计师提供了无限的创意空间。本文将深入剖析<ul>标签的内核,详细…...

MongoDB日志级别
日志 查看当前的日志级别 根据你提供的 MongoDB 命令结果,命令 db.adminCommand({ getParameter: "logComponentVerbosity" }) 返回了 "ok" : 0,这意味着命令执行失败,没有成功获取到日志级别的配置信息。错误信息 &quo…...
Softmax回归--分类--有监督
输出和类别的维度一样。 一、当我们想将先线性层的输出直接视为概率,存在一些问题: 1.不能限制输出数字总和为1。 2.不能保证都是正数。 所以会使用softmax进行归一化。 二、交叉熵损失 交叉熵是一个衡量两个概率分布之间差异的很好的度量࿰…...

Jenkins生成html报告
下载插件 1.需要下载插件 html Publisher plugins 2.下载Groovy(设置css样式),默认没有css样式 在Job配置页面,增加构建步骤Execute system Groovy script,在Groovy Command中输入上面命令,即可: System.…...
牛客——查找字符串
B-你好,这里是牛客竞赛_牛客周赛 Round 59 (nowcoder.com) 返回值是子串或字符在 string 对象字符串中的位置 #include <bits/stdc.h> using namespace std; int T; string s; int main() { cin >> T; while(T --) { cin >>…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...