0-1背包问题(DP)-超有趣版


文章目录

  • 0-1背包问题(DP)-超有趣版
  • 一、 0-1背包问题
  • 二、 0-1背包问题分析
  • 三、0-1背包问题——DP算法求解
  • 四、0-1背包问题——DP算法深入分析
  • 五、代码实现

一、 0-1背包问题

一个小偷准备去一个大户人家偷东西,但是这个小偷比较瘦小,考虑到偷太多东西背不动,于是就从家里拿了一个小背包,背包容量为W=10。嘿嘿,万事俱备只欠东风,趁着月黑风高,潜入大户人家,直奔保险柜,经一番操作,打开保险柜,嘿嘿,发现里面有5个物品,分别是“金条”、“大洋”、“茅台”、“手镯”、“银戒指”。哇!发财了啊!
可是,可是我的包包就这大,该怎么装,装到的总价值最大呢?(采用自底向上的动态规划方法求解,得到最大装包价值为是多少?)

二、 0-1背包问题分析

背包的容量为10,用“W”表示,W=10
保险柜中物品的重量和价值分别表示如下

i(物品序号) 1(金条) 2(大洋) 3(茅台) 4(手镯) 5(戒指)
w(重量) 2 2 6 5 4
v(价值) 6 3 5 4 6

此时小偷瞅了一眼自己的小背包,天哪,包包有点小了,装不下哎。这个小偷也不笨,心想既然装不完,那也要选择一个最优装包方案,使得背包最后总价值最大,咱要做一个精明的小偷。
可是怎么样装才是一个“一个最优装包方案”呢?妈耶,小偷头都大了。这个时候就要考验小偷的强大的心理素质了,小偷突然想到小时候看的动画片“一休哥”。师傅分别叫一休哥和出货师弟把一袋米撵成粉,谁先撵完,奖励一碗炒米粉。吃货师弟听到优先撵完,奖励炒米粉一碗,那是两眼放光,拿起碾子开始拼命撵米,一休哥就不一样了,他把米按粒分给师兄,每个人只需要撵三粒,一会功夫一袋米已撵成粉,吃货师弟累的满头大汗,还有大半袋米没有撵。一休哥巧妙的运用了分治思想,将一个原问题最优解进行分解成子问题最优解,从子问题中得到原问题的最优解。
于是小偷就想到我是不是也可以把“一个最优装包方案”,进行分解成子最优装包方案,从子装包方案的最优结果推出更大规模问题的最优结果。

小偷推断出本问题具有最优子结构
最优子结构:一个问题的最优解包含其子问题的最优解,我们就称此问题具有最优子结构。

小偷心想,对“一个最优装包方案”进行求解时,每次产生的子最优装包方案并不总是新问题,有些子最优装包方案会被重复计算多次。果然是精明的小偷,为了避免重复计算,浪费逃跑时间,就对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。

小偷推断出本问题具有重叠子问题
重叠子问题:子问题的计算出现重复,填表解决。

即某阶段小偷背包状态一旦确定,就不受这个背包状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。

小偷推断出本问题具有无后效性
无后效性:每个状态都是过去历史的一个完整总结,

综上所述0-1背包问题具有最优子结构、重叠子问题和无后效性,满足运用动态规划算法(dp)解决问题的基本条件。
注意: 动态规划法与分治法最大的差别是:动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)

三、0-1背包问题——DP算法求解

动态规划的设计有着一定的模式,一般要经历以下几个步骤。
(1)划分阶段:
原问题的最优解,可划分为每个阶段的最优解的和。即max(V1Q1+V2Q2+…+VnQn);Qi取0表示“不装”,取1表示“装入”。

(2)确定状态和状态变量:
构建C数组的含义,C[i][j] :代表的是前 i 个物品加入容量为 j 的背包里面价值总和的最大值

(3)确定决策并写出状态转移方程:
C(i,j)={0,若i=0或j=0C(i−1,j),若w[i]>j,即包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);max{C(i−1,j),C(i−1,j−w(i))+v(i)},其他,有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个C(i,j) = \begin{cases} 0, & \text{若i=0或j=0} \\[5ex] C(i-1,j), & \text{若w[i]>j,即包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);} \\[5ex] max{C(i-1,j),C(i-1,j-w(i))+v(i)}, & \text{其他,有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个} \\[5ex] \end{cases} C(i,j)=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧​0,C(i−1,j),max{C(i−1,j),C(i−1,j−w(i))+v(i)},​若i=0或j=0若w[i]>j,即包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);其他,有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个​
(4)寻找边界条件:
W1Q1+W2Q2+…+WnQn<背包容量(W=10)

四、0-1背包问题——DP算法深入分析

采用采用自下而上的动态规划方法,先计算最小的子问题的最优解,再一层层组合成大问题的最优解,计算过程中不存在子问题的重复计算。思路比较简单,就是不断遍历,不断填充C表:

第一:根据C(0,j)=C(i,0)=0;初始化表格:

i/j 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0
1 0
2 0
3 0
4 0
5 0

第二:当 i=1的时候,只有物品1能够选择,i=1,j从1开始取,w(1)=2,v(1)=6,如果背白容量j>w(1),则装入,那么此时的最大价值就是物品1的价值

i/j 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 6 6 6 6 6 6 6 6 6
2 0
3 0
4 0
5 0

第三:当i=2的时候,j=4从开始取,表示足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个。根据状态转移方程,此时取i=2,j=4的时候有如下转换:
i=2,j=4,w(2)=2,v(2)=3
故C(2,4)=max{ C(2-1,4),V(2-1,4-w(2))+v(2) }=max{6,6+3}=9
依次类推直到填完整张表,可得最优装包方案使得背包总价值最大。

i/j 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 6 6 6 6 6 6 6 6 6
2 0 0 6 6 9
3 0
4 0
5 0

采用自底向上的动态规划方法求解,填完整张表,得到最大的装包价值为15。

五、代码实现

#include "math.h"
#include "stdio.h"
#include "string.h"
int seekMax(int N, int M, int V[], int W[]);
int main(){int N = 5; //物品的数量int M = 10; //背包的容量int V[] = {0,6,3,5,4,6}; //物品的价值  前面的0就是占位的,方便遍历int W[] = {0,2,2,6,5,4}; //物品的重量int re = seekMax(N, M, V, W);printf("%d", re);
}
//优化得
int seekMax(int N,int M,int V[],int W[])
{//1、创建C数组int C[M+1];//2、初始化C数组for (int j = 0; j <= M  ; j++){C[j] = 0;  //初始全部都为0}//3、开始根据状态转移方程地推填满C数组for (int i = 1; i <= N; i++){for (int j = M; j >= W[i]; j--){C[j] = fmax(C[j], C[j - W[i]] + V[i]); //可以装下,可以选择 拿或者不拿}}return C[M];
}

0-1背包问题(DP)-超有趣版相关推荐

  1. 动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包,混合背包

    动态规划dp(带模板题の超易懂版):01背包,完全背包,分组背包,多重背包 01背包 && 完全背包 && 分组背包 の 视频教程:https://www.bilibi ...

  2. 多米诺骨牌——变形版0,1背包问题

    多米诺骨牌--变形版0,1背包问题 1.题目描述 2.问题分析 3.算法源码 1.题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的上方块中点数之和记为S1,下方块中点数之和 ...

  3. 区间DP解析超详细版!!街边老奶奶也喜欢看的好博客

    区间DP解析超详细版!! 文章目录 区间DP解析超详细版!! 1. 概念入门 2. 线性石子归并 3. 环形石子归并 4. 奇怪的题题目目 5. 区间DP的优化 附录 在上章 背包 (<-点击传 ...

  4. no.7_qzhai 开心版_传世霸业超变版下载-传世霸业超变版手机版下载v1.0

    传世霸业超变版是一款有着超变态爆率的传奇游戏,在这款游戏中打造了经典的场景,有着与众不同的精彩活动内容等你体验,最畅爽的刷怪玩法,多元化的系统功能,每分钟都会让你感受到极致爆率的精彩传奇,挂机模式让你 ...

  5. 第5讲:27条超有趣的Linux命令

    27个有趣的Linux命令,假装自己是命令行黑客高手. 本文向新手介绍了Linux操作系统基本原理.命令行基本操作,以及"管道"的概念.这些命令可以在树莓派和Ubuntu系统上运行 ...

  6. 用滚动数组求解0/1背包问题

    用滚动数组求解0/1背包问题(此处仅求装入背包的最大价值) // 由于第i个阶段(考虑物品i)的解dp[i][ * ]只与第i-1个阶段(考虑物品i-1)的解dp[i-1][ * ]有关,这种情况下保 ...

  7. python3.7 百度网盘_编程开发工具Python v3.7.0 32/64位免费正式版下载[网盘资源] - 艾薇下载站...

    Python3.7.0是一款超好用的面向对象编程的语言功能,也是一种简单易学却功能强大的编程语言,对于初学者来说,作为入门语言可以说是十分合适了.不像是C语言.C#语言一样,晦涩难懂,要求专业性比较高 ...

  8. P2668 斗地主 dp+深搜版

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  9. 酷安应用市场php源码,酷安应用市场 v11.0.3-999 去广告极限精简版

    酷安,真实有趣的数码社区.酷安app,国内安卓应用市场客户端,应用资源丰富,应用开发者水准高,应用无首发Logo,原汁原味上架,得到了安卓用户群广泛认可.有人说现在的酷安市场(酷安网)没有以前那么纯粹 ...

最新文章

  1. mysql象限和投影_PostGIS空间数据库SRID背景知识 - 地理坐标系(球面坐标系)和投影坐标系(平面坐标系) - GIS开发者...
  2. Kettle连接HiveServer2配置和常见问题解决
  3. (转)用ASP.NET向Javascript传递变量 方法1:
  4. 内部类、包、修饰符、代码块
  5. saltstack mysql_saltstack学习五:return及入库_MySQL
  6. String.valueOf() 和 toString的区别
  7. Java Server Page
  8. NLP预训练家族 | Transformer-XL及其进化XLNet
  9. mybatis事物如何避免脏读_新手指南:如何从java电商小白到秒杀大咖
  10. LANMP架构----------------------mysql(2)
  11. 一阶惯性环节如何实现跟踪性能与滤波性能共存(一)
  12. 网络编程-UDP编程
  13. TI深度学习(TIDL)--1
  14. python的词性标注
  15. 硬盘格式化工具 标记坏扇区_硬盘格式化后是否还记得坏扇区?
  16. Ubuntu使用sudo cp命令复制文件夹时出现“cp: omitting directory”问题
  17. h5 app跳转客服咨询 临时会话 (没有开通在线咨询、无法会话)
  18. windows键盘按键输入错乱;
  19. springboot2.x整合tkmapper
  20. shopee数据分析:虾皮卖家如何正确分析shopee卖场数据?

热门文章

  1. linux 怎么退出pr命令,Linux pr 命令 command not found pr 命令详解 pr 命令未找到 pr 命令安装 - CommandNotFound ⚡️ 坑否...
  2. 6年后端高级开发,腾讯面试多次被否心灰意冷,网友评论正中要害
  3. Zigbee/matter/Thread技术常用名词的中英文对照
  4. 善良的力量可以像滚雪球,越滚越大
  5. 15年双11手淘 H5性能最佳实践
  6. 为什么越来越多大学生沉溺于游戏中? ---游戏设计思路
  7. 【59区】为什么手机一直没有屏下摄像头?三星好像要“搞事情”了!
  8. 搜索引擎排名威新hfqjwl_seo快速排名威新hfqjwl
  9. Flash&Flex相关资料
  10. 定时删除30天之前的文件