利用0-1背包问题谈动态规划

动态规划之0-1背包问题(详解+分析+原码) 本篇文章将介绍算法专题之动态规划中的背包问题,更准确的说是背包问题中最简单的一种类型,即0-1背包问题,就是给你一定容量的背包和若干物品,每种物品只能选一次,告诉你每件物品的价值和体积,求背包里面物品的最大总价值。 阅读详情

动态规划解释

维基百科的定义:
- 动态规划的本质,是对问题状态的定义和状态转移方程的定义。引自维基百科

dynamic programming is a method for solving a complex problem by    breaking it down into a collection of simpler subproblems.

动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。如何拆分问题,才是动态规划的核心。而拆分问题,靠的就是状态的定义和状态转移方程的定义。

什么样的问题适合使用动态规划 ?

(1) 满足动态规划的最优化原理:
作为整个过程的最优策略具有如下性质:无论过去的状态和决策如何,对前面的决策所形成的当前状态而言,余下的诸决策必须构成最优策略。 可以通俗地理解为子问题的局部最优将导致整个问题的全局最优,即问题具有最优子结构的性质,也就是说一个问题的最优解只取决于其子问题的最优解,非最优解对问题的求解没有影响。
(2)满足动态规划的无后效性原则:
所谓无后效性原则,指的是这样一种性质:某阶段的状态一旦确定,则此后过程的演变不再受此前各状态及决策的影响。也就是说,“未来与过去无关”,当前的状态是此前历史的一个完整总结,此前的历史只能通过当前的状态去影响过程未来的演变。具体地说,如果一个问题被划分各个阶段之后,阶段 I 中的状态只能由阶段 I+1 中的状态通过状态转移方程得来,与其他状态没有关系,特别是与未发生的状态没有关系,这就是无后效性。

解题步骤是怎样?

1、状态的定义
2、状态转移方程的建立
状态即问题的子问题,之所以叫状态是为了防止混淆原问题,用计算机来表示就是用哪些变量存储哪些数据。状态转移方程,当状态定义好后,他们之间的转换关系就是状态转移方程,用计算机表示就是怎样根据一些变量计算出另一些变量。下面我将通过0-1背包问题来像大家解释以上概念,方便大家理解。

问题描述

现有n件物品和一个容量为c的背包。第i件物品的重量是重量为w[i],价值是v[i]。已知对于一件物品必须选择取(用1表示)或者不取(用0表示),且每件物品只能被取一次(这就是“0-1”的含义)。求放置哪些物品进背包,可使这些物品的重量总和不超过背包容量,且价值总和最大。

问题分析

这个问题特点是,每种物品只有一件,可以选择放或者不放, 假设我们从没见过这个题,所以我们要先分析下是不是适合使用动态规划,先从第一点来看是不是符合最优子结构。设背包最大容量C,如果某个状态的最优解包含了物品n,那么其余X1、X2、…Xn-1 一定构成了子问题1,2,…n-1在容量为C-cn适合的最优解,如果这个最优解不包含物品n,那么其他X1…Xn-1 一定构成了子问题 1、2…n-1在容量为C时候的最优解。我们可以用反证法来证明上述,如果在某个状态的最优解包含了物品n,如果在其余X1、X2、…Xn-1
没有构成子问题1,2,…n-1在容量为C-cn适合的最优解,那么必定存在一个其他组合方式能使该子问题达到最优解的,那么这就与题目1、2…n-1在容量为C时候的最优解冲突了。因为假设某个问题最优解包含了物品n的时候的价值是8,体积为8,如果去掉物品n后价值为5,体积为5,如果其他物品没有构成在体积为5下的最优解的话,那么就存在其他组合方式能让体积为5的时候价值大于5,那么再加上物品n的话总价值就会大于8,与假设不符,因为假设是8为最优。所以通过上述分析,该问题是具备最优子结构性质的。
那么再来看看是不是符合无后效性,当你知道物品总体积为C的时候你想加入一个cn,所以加入之前体积为C-cn,假设价值为x,加入后价值为y,你根本不用管这x怎么来的,到底是加入了哪些物品才得到了x,这些你都不用管,因为y的得到只需要x加上物品n的价值就行了,不关心你怎么来的,所以x为以前历史的一个总结。

解题

int c[N]; //存储物体体积
int v[N];//存储物体价值
int i,j; //物品序号、当前体积。

1、状态定义
我们可以先这样考虑,当背包容量为1时,如何放置物品才能使背包中价值最大;同样当背包容量为2时,如何放置能使背包中价值最大,以此类推,直到背包容量为10。此时我们需要维护一张二维表m[i][j],其中横坐标i表示物品,纵坐标表示背包容量(1<=j<=10)。

0-1背包问题的递推二维表
0-1背包问题的递推二维表

可以将每个重量的时候看成是一个状态。
2、状态转移方程式建立
通过上表可以看到,当横坐标到了一定体积的时候,如果当前c[i]小于j,那么就可以选择加入 或者不加入,如果加入后总价值比原来的大,那么肯定加进去,如果没有原来大则不加。当前价值为m[i-1][j],加入前价值为m[i-1][j-c[i]],加入后价值为加入前加上物品重价值,即m[i-1][j-c[i]+v[i],通过上述便可建立状态转移方程式了。
(1)i=0 当j<c[0]时,m[0][j]=0;当j>=c[0]时,m[0][j]=v[0]。
(2)i>0 当j<c[i],m[i][j]=m[i-1][j];当j>=c[i],m[i][j]=max{m[i-1][j-c[i]]+v[i],m[i-1][j]}。

编码

这儿我只列出核心算法代码

for(int i=1;i<N;i++){
for(int j=1;j<=C;j++){
   if(c[i]<j){ //可以加入
    m[i][j]= max(m[i-1][j],m[i-1][j-c[i]]+v[i]);
     }else{ //加不进
          m[i][j]=m[i-1][j];
           }
}
}

总结

至此利用0-1背包问题谈动态规划已经结束了。总结一下,其实动态规划是用来解决一类问题的,其核心应该是状态定义,而不是状态转移方程式的建立。一个问题状态的定义有很多种,状态转移方程式也有很多种,甚至存在一个有后效性的定义,但是并不代表不能用动态规划,只是不适合罢了。动态规划是寻找一种对问题的观察角度,让问题能够以地推或者分治的方式去解决。所以寻找看问题的角度,才是动态规划中最耀眼的宝石。

感谢

动态规划理解 徐凯强
0-1背包详解

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

相关推荐

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

关于背包问题,其实可以分为两种类型:0-1背包问题 和 部分背包问题。 1、先通过一个例子来说明一下二者的区别吧! 有一个窃贼在偷窃一家商店时发现有n件物品,第i件物品价值为vi元,重量为wi,假设vi和wi都为整数。他希望带走的东西越值钱越好,但他的背包中之多只能装下W磅的东西,W为一整数。他应该带走哪几样东西? 0-1背包问题:每件物品或被带走,或被留下,(需要做出0-1选择)。小偷

小邓笔记 3万+

【动态规划专栏】-- 01 背包问题 -- 动态规划经典题型

4道《01背包问题》动态规划算法经典题型

weixin_64609308的博客 7923

动态规划法如何来解决0-1背包问题

1、0-1背包问题。设有n个物品他们的重量和价值分别存放在数组w[]和v[]中,背包的容量存放在全局变量C中,和最终的n个物品是否装入情况存放在数组x[n]中。 2、int KnapSack(int w[],int v[],int x[],int n)函数功能是返回能装载的最大价值。并且第i个物品能否装入背包存放在数组元素x[i]中,它为1(非0)表示该物品可以装入,为0表示该物品不装入。 3、写主函数main(),实现输入数组w[]和v[],调用KnapSack函数,并输出装入物品的编号。 (1)解题思路

JobinXin的博客 3332

【动态规划】01背包问题(手画图解)

01背包问题是所有背包问题的根本所在,掌握好dp五部曲,明确dp及其下标含义,勤加练习是制胜之道!

这个人很勤快,但还是什么也没有。 7601

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

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

linweieran的博客 4045

NVIDIA显卡驱动历史版本全攻略:从官网隐藏入口到精准下载

本文详细介绍了如何获取NVIDIA显卡驱动历史版本的完整攻略,包括官网隐藏入口的揭秘、精准筛选驱动版本的技巧以及安装避坑指南。特别针对游戏玩家、创作者和老显卡用户提供了实用建议,帮助用户解决驱动兼容性问题,提升显卡性能。

m2n3o4p5的博客 3723

动态规划背包问题之01背包详解

动态规划背包问题之01背包详解

晨的博客 5万+

工业机器人关节拆装流程_一文读懂模块化直驱电机及机器人关节模组

私信“干货”二字,即可领取138G伺服与机器人专属及电控资料!如果说芯片是智能行业最为重要的核心元件,那么电机几乎可以说是支撑了整个自动化和大工业生产以及现代社会最为重要的部件,全世界90%的能源是由电机发出来的,而70%是由电机消耗调的,电机可以说是整个人类社会能源循环的占有绝对地位的产品。普通伺服电机伺服电机其实已经算是电动机中比较高端的类型,特别是永磁同步类型的伺服电机,由于其启动快速,惯量...

weixin_32159771的博客 2153

动态规划——01背包,完全背包,力扣题型讲解

本文带你解决力扣上所有典型的背包问题,通俗易懂的讲解。

weixin_43757333的博客 3762

RAG开源框架深度评测:从RAGFlow到Dify的实战选型指南

本文深度评测了主流RAG开源框架(RAGFlow、Dify、WeKnora)的核心能力与实战表现,提供企业级选型指南。重点对比了文档解析、检索性能和生产部署等关键指标,揭示RAGFlow在复杂文档处理、Dify在低代码开发、WeKnora在腾讯生态集成的差异化优势,并给出技术选型决策树与成本优化方案。

weixin_29294597的博客 825

UCIe相关开源项目记录

目前找到的和UCIe协议有关的5个开源项目,如果也有正在做的朋友,欢迎私信交流

m0_64102565的博客 822

彻底搞懂0-1背包问题(动态规划)

看了很多网上的博客,发现对于0-1背包问题很多讲的都很专业,初学者学起来还是比较吃力,今天我就用最简单最形象的语言来描述一下0-1背包问题,为什么不能用贪婪算法,而要选择使用动态规划。 首先对于0-1背包问题,我们需要知道的是:每一个物品只有1个,要么全拿,要么不拿,最后使得拿到的物品的总价值最大。 假如一个小偷有一个可以容纳4千克的背包,但是发现面前只有有3样物品可以偷:台灯(30元,4千克)、音响(20元,3千克)、充电宝(15元,1千克)(价格和重量可能有点奇怪????)。问,小偷能够偷到的物品的

HarryXu的博客 2万+

如何快速获取SAMM、SMIC等主流微表情数据集?完整申请指南(附避坑技巧)

本文提供了获取SAMM、SMIC等主流微表情数据集的完整申请指南,包括申请前的准备工作、分步申请流程、协议谈判技巧以及数据使用与维护策略。特别针对高分辨率动态捕捉和多模态同步数据等热词,帮助研究者高效获取高质量数据集,避免常见陷阱。

weixin_29057163的博客 420

九种 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万+

【WRF数据准备】海温(SST)数据替换

【WRF数据准备】海温(SST)数据替换

WW、forever的博客 1117

【Bug已解决】codex: rate limit 429 / Too many requests / RPM exceeded — CodeX CLI 速率限制解决方案

CodeX CLI 触发 429 速率限制(RPM/TPM/并发)的解决方案,含请求间隔、自动重试、便宜模型、Tier 升级与多 Key 轮换。

博客 4890

动态规划-(0-1)背包问题

下面我用容积代表重量(我是不会承认我看走眼了的。又懒得改。)0-1背包问题是动态规划背包问题系列的最基础的一个问题。相对理解起来较为简单。按书上来说,要证明一个问题是否可以使用动态规划思想,需要满足最优子结构的性质,那么什么是最优子结构的性质呢?书上给出的定义如下图看起来很拗口,其实就是不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。说白了就是一个最优策略的子策略也是必须是最优的,而所有子问题的局部最优解将导致整个问题的全局最优。

菜鸟的博客 1万+

YOLOv11涨点改进 | 检测头Head改进篇 | 利用DynamicConv高效动态卷积改进YOLOv11检测头,DyHead通过增强检测头操作,轻量化改进、提高模型目标检测的精度

本文提出了一种基于动态卷积(DynamicConv)的YOLOv11检测头改进方法v11Detect_DyHead。该方法通过引入多专家机制和动态权重调整,在增加参数量的同时保持较低计算复杂度,有效解决了低FLOPs模型难以从大规模预训练中获益的问题。文章详细介绍了DynamicConv模块的原理和实现,包括其参数高效特性、多专家机制和动态权重生成方式。同时提供了完整的代码实现和添加该模块的具体步骤,并给出了相应的YAML配置文件。实验表明,该方法在保持较低计算开销的同时显著提升了模型性能,适用于视觉和语言

Ai缝合怪、助力小伙伴高效发论文 534

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

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

weixin_49571787的博客 6432

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

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

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

动态规划法解决0-1背包问题(C++)

1.动态规划法的设计思想:动态规划法将待求解问题分解成若干个相互重叠的子问题,每个子问题对应决策过程的一个阶段,子问题的重叠关系一般表现在对给定问题求解的递推关系,将子问题的的解求解一次并且填入表中,当需要再次求解子问题的时候,可以通过查表获得这个子问题的解而不是再次求解,从而避免大量重复计算,为了达到这个目的,可以通过一个表来记录所有以解决的子问题的解。 2.动态规划法求解的问题的特征:该问题的

黄鸟于飞 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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

待续。。。 代码实现 package com.zzb.algorithm.dynamic; /** * 动态规划算法 * 应用实例:0-1背包问题(限制每个物品要么拿(1个),要么不拿(0个)) */ public class KnapsackProblem { public static void main(String[] args) { // 每个物品的重量 ...

花开归矣的博客 8030

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

动态规划0—1背包问题

动态规划0-1背包问题 Ø    问题描述:    给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装 入背包中物品的总价值最大? Ø   对于一种物品,要么装入背包,要么不装。所以对于一种物品的装入状态可以取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题。

逐梦科学 16万+

0-1背包问题(动态规划)

动态规划的核心思想就是把一个大问题分解成很多小问题,然后逐个解决这些小问题,最后把这些小问题的解组合起来,就得到了大问题的解。为什么要用动态规划?有些问题直接解决很难,但是分解成小问题就容易多了。很多小问题是重复的,我们可以把这些小问题的解保存起来,避免重复计算。背包问题,就像在玩一个非常有趣的“装箱”游戏!想象一下,你有一个背包,它只能装下一定重量的东西。现在,你面前有一堆玩具,每个玩具都有自己的重量和价值,每个玩具只能装一个。在背包的重量限制下,装下尽可能多的玩具,并且让这些玩具的总价值最高。

m0_74062928的博客 2700

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

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

yw906002599的博客 1万+

动态规划之经典案例《0-1背包问题》详解

0-1背包问题描述 有一个可装重量为w的背包和n件物品,每件物品都有重量和价值两个属性,且每件物品只有一件,只能选择装入或者不装,能装入的最大物品价值是多少? 一、贪心算法分析 看到求最值问题,一般是使用动态规划来解。为什么不使用贪心算法来解?因为贪心算法求的是局部最优解,而动态规划才能求得全局最优解。 举个例子: 现在有以下物品重量和价值数组W、V,背包最多装入9kg物品。 W = [4,6,5,2] V = [7,8,5,3] 使用贪心算法时,每一步要做的就是对于第i件物品,我取还是不取,且只能抉择

mbytes的博客 4399

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

【0-1背包问题描述】【0-1背包动态规划解法思路】【0-1背包动态规划状态转移方程及默认值】【0-1背包动态规划解法的Java代码实现】

王喆峰的博客 1万+
上一篇: Android IPC多进程通信总结
下一篇: 动态规划之线性动规钢条切割问题
HJsir
博客等级 码龄10年 19粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值