动态规划学习-【0-1背包问题的优化和变种】

动态规划之01背包问题+状态压缩(hihocode#1038) 01背包问题解释详见博客:https://blog.youkuaiyun.com/mu399/article/details/7722810此博客主要介绍如何减低空间复杂度,对应题目hihocode #10381.先附上最普通没有任何优化的写法#include <cstdio> #include <iostream> #include <algorithm> #define... 阅读详情

0-1背包问题的基本描述和解题算法请看:

动态规划学习-【0-1背包问题】

上面这篇文章我们已经得出0-1背包问题的状态转移方程:

F(n, C)考虑将n个物品放进容量为C的背包,使得价值最大:

F(i, C) = max( F(i - 1, C), v(i) + F(i - 1, C - w(i)))

1. 空间复杂度为:O(2 * C)

根据状态转移方程,我们可以分析出来,第i行元素只依赖于第i-1行元素。理论上,只需要保持两行元素。空间复杂度变为:O(2 * C) = O(C)。

具体操作: 

首先,初始化i = 0 行的数值。(行表示物品索引,列表示背包剩余容量)

其次,i = 1 这一行的数据要根据i = 0行的数据进行计算。

然后,计算 i = 2这一行,i = 2这一行依赖于i = 1行。针对这一步,其实我们有两种操作办法:第一种,把 i = 1 行往上移动,覆盖原有的i = 0行数据,i = 2行覆盖i = 1行;第二种,把 i = 2行直接覆盖 i = 0行。我们采用第二种方法,如果采用第一种方法会导致时间耗费增加。

接着, i = 3行可以直接覆盖掉i = 1行。

最后,根据以上操作,我们会发现上面行永远在记录i = 偶数的行、下面行永远在记录 i = 奇数的行。

在实际编程中,我们计算第i行,它依赖于第 i - 1行,我们直接根据i是奇数和偶数来进行取值计算。

class Solution:

    def knapsack01(self, w, v, C):

        assert len(w) == len(v)

        if len(w) == 0 or len(v)== 0:
            return 0

        memo = [[0 for i in range(C + 1)] for _ in range(2)]

        for i in range(C + 1):
            memo[0][i] = v[0] if i >= w[0] else 0

        for i in range(len(v)):
            for j in range(C + 1):
                memo[i % 2][j] = memo[(i - 1) % 2][j]
                if j >= w[i]:
                    memo[i % 2][j] = max(memo[i % 2][j], v[i] + memo[(i - 1) % 2][j - w[i]])

        return memo[(len(v) - 1) % 2][C]

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

 2. 空间复杂度为:O(C)

第 i 行元素只依赖于第 i-1 行元素。理论上,只需要保持两行元素。空间复杂度为:O(2 * C) = O ( C )。

思考:只使用一行大小为C的数组完成动态规划?

 我们再来分析一下,当我们使用两行空间时候的计算过程。第 0 行已经初始化完成,第 1 行已经计算了一半,当C = 2时,已经可以容纳id = 1的物品。这时,我们要考虑我们的状态转移方程,F(1, 2) = max(F(0, 2), 10 + F(0, 0))。我们可以注意一下,F(1, 2)只和它左边和上边的数值有关,和 i = 0 行的右边元素无关。因此,我们可以考虑在这个点上做优化。

当我们只有i = 0 这一行内容时,因为 i =1行只与i = 0行的左边内容有关。因此,当我们计算i = 1行时,可以考虑从i = 0 行的右边开始刷新内容。

下图是计算F( 1, 5) = max(F(0, 5), 10 + F(0, 5 - 2))

下图是计算F(1, 4) = max(F(0, 4), 10 + F(0, 4 - 2)) 

 

 下图是计算F(1, 3) = max(F(0, 3), 10 + F(0, 3 - 2)) 

  下图是计算F(1, 2) = max(F(0, 2), 10 + F(0, 2 - 2)) 

 

 由于F(1, 1)中背包所容纳重量已经不能放置 i = 1 的物品,所以 F(1 , 1)左边所有表格都不用再更新。这样的话,可以提前终止循环判断,提高了时间效率。

 代码实现:

class Solution:

    def knapsack01(self, w, v, C):

        assert len(w) == len(v)

        if len(w) == 0 or len(v)== 0:
            return 0

        memo = [0 for i in range(C + 1)]

        for i in range(C + 1):
            memo[i] = v[0] if i >= w[0] else 0

        for i in range(1,len(v)):
            for j in range(C, -1, -1):
                if j >= w[i]:
                    memo[j] = max(memo[j], v[i] + memo[j - w[i]])
                else:
                    continue
        return memo[C]

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

3. 0-1 背包问题的变种

3.1 完全背包问题:每个物品可以无限使用。

虽然每个物品可以无限使用,但是背包的容量是有限的。背包可以装有限的物品,只是一些物品是重复的。

3.2 多重背包问题:每个物品不止1个,有num(i)个。

3.3 多维费用背包问题:要考虑物品的体积和重量两个维度?

3.4 物品之间加入约束

  1. 物品之间可以相互排斥。在背包中放入某个物品之后,就不能放入其他物品。
  2. 物品之间的相互依赖。在背包中放入某个物品,就必须放入另一个物品。
算法——动态规划之0-1背包问题 打算每天复习一点算法内容,就先从动态规划下手。曾经动态规划让我头疼,重新学了一下觉得还好啦不是很难,实现动态规划算法的核心在于实现它的递推公式,写出递推公式,代码也就很容易了。动态规划类似分治法,都是将一个大问题分解为一个个小问题,分而治之。不同之处在于,动态规划记忆了重复的子问题,避免了运算过程中的重复计算。适用情况:有重叠子问题和最优子结构性质(动态规划每一步求的都是最优解)的问题。下面我们通... 阅读详情

相关推荐

0-1背包问题:动态规划 python 空间优化

0-1背包问题总述 0-1背包问题是最简单的问题,此外还要完全背包问题、多重背包问题、混合背包问题、二维费用背包问题、分组背包问题等等。好的参考资料可以见《背包问题九讲》:https://www.kancloud.cn/kancloud/pack/70124 其中0-1背包问题是最基本的问题,其问题描述如下: 给出n个珍珠的体积v[i]和其价值price[i],将他们装入一个大小为C的背包,...

linweieran的博客 4045

0-1背包问题的优化

n是物品的个数,c是物品的容量。对于0-1背包问题,它的时间优化空间已经非常小了,但是空间还有很大的优化空间。 0-1背包问题相应的状态转移方程 对于状态转移方程,它有这样的一个特点,每一次只更新一行的内容,而每一次所更新的那一行的内容,比如第i行的内容,它只依赖于第i-i行的内容,而不用去考虑i-1行之前的那些元素具体是什么样子的。换句话说,只要求出一行,就能求出下...

nicolelili1的专栏 4449

【Algorithm】0-1背包问题及其价值

0-1背包问题(0-1 Knapsack Problem)是一种组合优化问题,它是背包问题的一个特殊变体。在这个问题中,你给定一组物品,每个物品都有一个重量和一个价值。目标是选择一些物品放入背包中,使得背包中物品的总价值最大,同时不超过背包的最大承重限制。0-1背包问题的特点在于每个物品只能选择0个(不选)或1个(全选),不允许分割物品。给定一个物品集合,其中每个物品i都有一个重量w_i和一个价值v_i。背包有一个最大承重限制W。目标是找到一个物品的子集,使得子集中物品的总价值V。

格物致知 1107

动态规划-经典问题(0-1背包问题)分析及优化

目录 1.0-1背包问题的分析 (1)状态方程 2.递归算法 3.记忆化搜索 4.动态规划 5.优化1——空间复杂度O(2C) 6.优化2——空间复杂度O(C) 7.0-1背包问题的变种 如上图是一个LeetCode的经典问题,0-1背包问题 1.0-1背包问题的分析 尝试下面的算法 暴力解法:每一件物品都可以放进背包,也可以不放进背包,时间复杂度为O((2^n)...

YY-帆S的博客 1万+

【算法-动态规划】0-1 背包问题

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨。

优快云站内信: https://i.youkuaiyun.com/#/msg/chat/qyj19920704 1万+

01背包问题及变种详解

经典的背包问题九讲文档,包含了01背包及其变种的详细解释。

基于遗传算法的多目标优化进行0-1规划

使用python的DEAP库,实现基于遗传算法多目标优化的0-1规划模型。

m0_61860989的博客 3982

【MagicDrive环境配置】新手配俩星期版

1.创建一个新的环境conda create -n newdrive python==3.82.激活该环境conda activate newdrive3.下载MagicDrive源码 git clone --recursive https://github.com/cure-lab/MagicDrive.git,如果出现时间超时八成是网的问题,直接自己下载解压就好3.我的cuda版本是11.7,但11.7导致后续安装有冲突,因此进入。

m0_46261292的博客 2203

01背包问题的变种问题(奇行种)

01背包问题的转化类型 文章目录01背包问题的转化类型[494. 目标和](https://leetcode-cn.com/problems/target-sum/)[1049. 最后一块石头的重量 II](https://leetcode-cn.com/problems/last-stone-weight-ii/) 494. 目标和 难度中等796 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : 例如

ahelloyou的博客 641

VIL-SLAM论文翻译:Stereo Visual Inertial LiDAR Simultaneous Localization and Mapping

文章目录写在前面摘要1.引言2.相关工作3.系统概述4.视觉前端5.双目视觉惯性里程计A. IMU预积分因子B. 非结构化视觉因子C. 优化和边缘化6. 激光建图A. LiDAR扫描去畸变B. 帧到地图配准7. LiDAR增强的闭环A. 回环检测B. 回环约束C. 全局位姿图优化D. 重定位8. 实验结果A.平台和软件B.测试和结果C. EuRoCMAV数据集测试9.结论 写在前面 写作参考: robot L 开源代码: 开源代码链接 论文原文: 原文链接 摘要 SLAM是移动和空中机器人的一项基本任务

JaydenQ的博客 2321

图像评价之计算PSNR、SSIM、MSE、LPIPS和NIQE评价指标

如果代码对你的研究有所帮助,请为该仓库点上小星星。

书山有路,学海无涯! 2648

算法学习篇12——背包问题

我们定义一个二维数组dpdp[i][w]:表示对于前i个物品,在背包容量为w时,能获得的最大价值。我们的目标就是求出dp[N][W]的值。核心思想:动态规划通过填表的方式,记录了所有子问题的解,避免了暴力搜索带来的指数级复杂度。适用场景:0-1背包问题,每个物品最多选一次。变种问题:完全背包:每种物品可以选择无限次。解决方案是内层循环从小到大遍历容量w。多重背包:每种物品有数量限制。分组背包:物品被分为若干组,每组内的物品互斥。学习建议:理解状态定义和转移方程是重中之重。

a19884792066的博客 718

软件工程大作业——图书管理系统/图书个性化推荐与实现系统

软件工程期末大作业,图书管理系统,包含ER图、程序流程图、属性图、结构图

2401_82857325的博客 3649

动态规划DP (update)

动态规划DP (update)

zbbxndm的博客 919

点云配准实战:用DGCNN+Transformer+SVD搞定3D模型对齐(附PyTorch代码)

本文详细介绍了基于深度学习的点云配准实战方法,重点解析了Deep Closest Point (DCP)模型。该模型融合了DGCNN、Transformer和可微分SVD三大核心模块,能够端到端地预测点云间的刚性变换,有效克服传统ICP算法对初始位置敏感、易陷入局部最优的缺点。文章提供了完整的PyTorch代码实现、ModelNet40数据集处理、训练策略及显存优化技巧,旨在帮助开发者在机器人、自动驾驶等领域实现精准的3D模型对齐。

weixin_29061041的博客 154

【STC32G12K128开发板】——搭建开发环境

Keil C251是美国Keil公司(该公司2005年被ARM公司收购)出品的针对251微控制器系列兼容单片机C语言软件开发系统。

qq_36139768的博客 1万+

九种 0-1 背包问题详解

目录 动态规划概念 问题1:0-1背包问题 问题2:完全背包问题 问题3:多重背包问题 问题4:混合背包问题 问题5:二维背包问题 问题6:分组背包问题 问题7:有依赖的背包问题(困难) 问题8:背包问题求方案数 问题9:背包问题求具体方案 前言 0-1 背包是一个经典的问题,之前也整理过一篇关于 0-1 背包的博客,当时只是整理了 0-1 背包问题的4 种解决方法。最近在复习算法,发现有很多 0-1 背包问题的衍生问题。0-1 背包问题的限制条件既可以是重量,也可以是容量,或者..

Tyler_Zx的博客 2万+

AUTOSAR AP——SM模块

对AUTOSAR AP中状态管理模块SM,从模块定义、总结等多方面进行了介绍。

weixin_43627682的博客 284

动态规划解0-1背包问题

动态规划解0-1背包问题 动态规划解0-1背包问题是一个十分典型案例,我从网上查询好多相关资料,但是大部分都深奥难懂,并不适合初学算法的小白,其中涉及的递推关系式、填表,以及最后的二维表简化为一维表的优化过程,好多都是一笔带过,所以,今天就尽我所能,来叙述一下对于0-1背包问题使用动态规划来求解。 要解决0-1背包问题,首先咱们要解决的是什么是动态规划。 动态规划 先说一说什么是动态规划。 动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题

weixin_49571787的博客 6432

传导案例:某医疗仪器传导骚扰整改案例

紫外线光疗仪是一种专业的医疗设备,主要用于治疗银屑病、白癜风等皮肤疾病。该设备采用物理治疗技术,通过特定波长的紫外线照射人体来达到治疗效果。自1984年窄谱中波紫外线(NB-UVB)应用于临床以来,该技术已成为治疗早期蕈样肉芽肿(MF)的有效方法之一。作为二类医疗器械,紫外线光疗仪必须符合严格的电磁兼容性(EMC)标准,这不仅关系到设备自身的稳定运行,更关乎患者的使用安全和治疗效果。紫外线光疗仪传导骚扰整改案例充分展示了系统性EMC设计的重要性。

m0_56451176的博客 340

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

动态规划——0/1背包问题(全网最细+图文解析)

01背包你真的掌握了吗?进来带你10分钟秒杀

Biteht的博客 6万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

动态规划之背包问题(C语言)

动态规划 动态规划(英语:Dynamic programming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题 动态规划思想大致上为:若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 由于通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算

一串代码的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

动态规划之0/1背包问题原理详解: 简明、细致、深入理解

动态规划,0/1背包问题,回溯

yw906002599的博客 1万+

动态规划」详解背包问题及实践(附C++代码)

背包问题是一个经典的组合优化问题,它可以被抽象为一个把物品放入背包中的过程,以求最终背包中物品价值的最大化。0/1背包问题是一个经典的动态规划问题,指的是有n个物品和一个容量为W的背包,每个物品只能选择装入一次或不装入。在装入背包的物品总重量不能超过W的前提下,选择物品装入背包中,使得背包中物品的总价值最大。

BXA 7322

动态规划学习-【0-1背包问题】

题目描述: 问题:0-1背包问题 描述:有一个背包,它的容量为C(Capacity),现在有n种不同的物品编号分别为0...n-1,其中每一件物品的重量为w(i),价值为v(i)。问可以向这个背包中盛放哪些物品,使得在不超过背包容量的基础上,物品的总价值最大。 解题思路: (1)暴力解法: 每一件物品都可以放进背包,也可以不放进背包,有种情况。我们再从这种情形中选出总价值最大的物品,...

Microstrong 6163

【动态规划 | 01背包】动态规划经典:01背包问题详解

01背包是动态规划的经典问题,要求在容量限制下选择最大价值的物品。本文将详解如何通过状态转移方程高效求解,并给出空间优化方案,帮助掌握这一基础算法模型。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 1444
上一篇: 动态规划学习-【0-1背包问题】
下一篇: 【Python】利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字
Microstrong0305
Microstrong0305 领域专家: 算法与数据结构技术领域 领域专家: 算法与数据结构技术领域
博客等级 码龄12年 6405粉丝 312原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值