【算法导论】0-1背包问题 与 部分背包
【0-1背包】 问题描述:n件物品,第i件物品价值 v[i] 元,重w[i] 磅。希望用 W磅的书包 拿走总价值最贵的物品。(物品不可以分割故称为0-1背包)
【部分背包】问题描述:n件物品,第i件物品价值 vi 元,重wi 磅。希望用 W磅的背包 拿走最重的物品。第i件物品可以都拿走,也可以拿走一部分。(物品可以分割所以称为部分背包)
注意:0-1背包不能用贪心算法求解。
原因:按照贪心算法,每一次拿的都是每磅最贵的物品。由于物品大小不同,有可能每磅最贵的不是最合适大小的。最坏的情况可能导致,背包没有装满,而且当前装的也不是最优的。
例如:10磅 A 价值60¥ ; 20磅 B 价值100¥;30磅 C 价值120¥; 背包重50磅
按照贪心算法 ,应该选择 A B (160¥) 但是最优的应该是 BC(220¥)
分析:没有装满的背包降低了平均每磅物品的价值,将物品装入时必须考虑
1)装入物品i后子问题的解
2)不装入物品i后子问题的解哪个最优。
这样导致了许多子问题重叠,而这又恰巧是动态规划特点。
部分背包,显而易见可以用贪心算法。
【0-1背包】问题描述:
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。所谓0-1背包,表示每一个物品只有一个,要么装入,要么不装入。
二, 解决方案:
考虑使用动态规划(dynamic programming)问题求解,定义一个递归式 opt[i][v] 表示前i个物品,在背包容量大小为v的情况下,最大的装载量。
opt[i][v] = max(opt[i-1][v] , opt[i-1][v-c[i]] + w[i])
解释如下:
opt[i-1][v] 表示第i件物品不装入背包中,而opt[i-1][v-c[i]] + w[i] 表示第i件物品装入背包中。
花费如下:
时间复杂度为o(V * T) ,空间复杂度为o(V * T) 。 时间复杂度已经无法优化,但是空间复杂度则可以进行优化。但必须将V 递减的方式进行遍历,即V.......0 的方式进行。
三,初始化:
(1)若要求背包必须放满,则初始如下:
f[0] = 0 , f[1...V]表示-INF。表示当容积为0时,只接受一个容积为0的物品入包。
(2)若要求背包可以空下,则初始化如下:
f[0...V] = 0 ,表示任意容积的背包都有一个有效解即为0。
具体解释如下:
初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。
如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,
其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。
如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,
这个解的价值为0,所以初始时状态的值也就全部为0了。
四,代码如下:
01背包,使用了优化后的存储空间
建立数组
f[i][v] = max(f[i-1][v] , f[i-1][v-c[i]] + w[i])
将前i件物品,放入容量为v的背包中的最大值。
下面介绍一个优化,使用一维数组,来表示
(1) f[v]表示每一种类型的物品,在容量为v的情况下,最大值。
但是体积循环的时候,需要从v----1循环递减。
初始化问题:
(1)若要求背包中不允许有剩余空间,则可以将f[0]均初始化为0,其余的f[1..n]均初始化为-INF 。
表示只有当容积为0 的时候,允许放入质量为0的物品。
而当容积不为0的情况下,不允许放入质量为0的物品,并且把状态置为未知状态。
(2)若要求背包中允许有剩余空间 ,则可以将f[1n],均初始化为0。
这样,当放不下去的时候,可以空着。
*/
- #include<iostream>
- usingnamespace std ;
- constint V=1000 ;//总的体积
- constint T=5 ;//物品的种类
- int f[V+1] ;
- //#define EMPTY//可以不装满
- int w[T] ={8 , 10 , 4 , 5 ,5};//价值
- int c[T] ={600 , 400 , 200 , 200 ,300};//每一个的体积
- constint INF=-66536 ;
- int package()
- {
- #ifdef EMPTY
- for(int i=0 ; i<= V ;i++)//条件编译,表示背包可以不存储满
- f[i] =0 ;
- #else
- f[0] =0 ;
- for(int i=1 ; i<= V ;i++)//条件编译,表示背包必须全部存储满
- f[i] = INF ;
- #endif
- for(int i=0 ; i< T ; i++)
- {
- for(int v= V ; v >= c[i] ;v--)//必须全部从V递减到0
- {
- f[v] = max(f[v-c[i]]+ w[i] , f[v]) ;//此f[v]实质上是表示的是i-1次之前的值。
- }
- }
- return f[V] ;
- }
- int main()
- {
- int temp = package() ;
- cout<<temp<<endl ;
- system("pause") ;
- return0 ;
【算法导论】0-1背包问题 与 部分背包相关推荐
- 算法导论之贪心算法(Huffman编码和拟阵)
贪心算法,在解决最优化问题上,通过得到子问题的局部最优解来合成问题的一个解,以局部最优选择来输出一个全局最优解. 问题要用贪心算法来求解,需满足和动态规划一样的最优子结构特征,同时还需要再每个子问题最 ...
- Python数据结构与算法(1.1)——数据结构与算法导论
Python数据结构与算法(1.1)--数据结构与算法导论 0. 学习目标 1. 数据结构概述 1.1 什么是数据结构 1.2 逻辑结构和物理结构 1.3 抽象数据类型 1.4 数据结构学习的必要性 ...
- 令人头疼的背包九讲(1)0/1背包问题
点击上方"Jerry的算法和NLP",选择"星标"公众号 重磅干货,第一时间送达 背包问题是一个经典的动态规划模型.它既简单形象容易理解,又在某种程 ...
- 算法之动态规划,问题三:0 1 背包问题
目录 1 问题的描述 2 贪心算法? 3 算法的参数约定及递推式 4 算法具体实现 5 回溯原问题的解 6 案例输出 7 源代码 1 问题的描述 0 1 背包的问题: 有n个物品(权重Wi>0, ...
- 算法设计与分析实验二:动态规划法实现TSP问题和0/1背包问题
[实验目的] 1.熟练掌握动态规划思想及教材中相关经典算法. 2.使用动态规划法编程,求解0/1背包问题和TSP问题. TSP问题 一.实验内容: TSP问题是指旅行家要旅行n个城市,要求每个城市经历 ...
- 分支限界法 01背包c语言,算法笔记分支限界法01背包问题
<算法笔记分支限界法01背包问题>由会员分享,可在线阅读,更多相关<算法笔记分支限界法01背包问题(12页珍藏版)>请在人人文库网上搜索. 1.问题描述给定n种物品和一背包.物 ...
- 背包问题(01背包,完全背包,多重背包(朴素算法二进制优化))
写在前面:我是一只蒟蒻~~~ 今天我们要讲讲动态规划中~~最最最最最~~~~简单~~的背包问题 1. 首先,我们先介绍一下 01背包 大家先看一下这道01背包的问题 题目 有m件物品和一个容 ...
- 《算法导论》读书笔记(七)
<算法导论>读书笔记之第16章 贪心算法-活动选择问题 前言:贪心算法也是用来解决最优化问题,将一个问题分成子问题,在现在子问题最优解的时,选择当前看起来是最优的解,期望通过所做的局部最优 ...
- 《算法导论》学习总结 — 21.第16章 贪心算法(1) 基础入门1
建议先看看前言:http://www.wutianqi.com/?p=2298 连载总目录:http://www.wutianqi.com/?p=2403 说到贪心算法,避免不了于DP对比,所以前面的 ...
- 八十九、动态规划系列背包问题之完全背包
@Author:Runsen @Date:2020/9/15 动态规划需要搞定三个系列:三个背包,零钱问题和股票问题.今天就开始干掉三个背包问题. 三个背包问题:01背包,多重背包,完全背包.上次搞定 ...
最新文章
- 有一个1亿结点的树,已知两个结点, 求它们的最低公共祖先!
- [react] 在React中如何判断点击元素属于哪一个组件?
- linux上git克隆命令,Git clone命令用法
- 掼蛋游戏WEB版——PHP后台实现源码
- Windows系统appium移动端自动化真机环境搭建
- Python 解释器中使用help()命令如何退出
- Kotlin入门(8)空值的判断与处理
- php 右下脚弹窗,多种样式jQuery网页右下角弹出提示信息代码
- Docker下安装Anaconda
- LINUX Telepresence编译详细过程记录
- mysql仓库管理软件破解版_Max(TM)仓库管理软件|Max(TM)仓库管理系统下载_v2.0.5.1 MySQL网络版_9号软件下载...
- CI框架 url指向错误 配置根目录
- JavaScript简易文字对战游戏
- EyouCms1.0前台GetShell漏洞复现
- java 序列号怎么获取,Java获得硬盘和主板的序列号代码
- origin画图对图片进行缩放时,如何不让文字一同缩放?
- linux0.11磁盘映像制作及其剩余程序阅读注释笔记
- 浅谈运维工程师的开发能力的培养
- Linux alias(别名)设置
- VM中调节系统窗口大小
热门文章
- Python深入理解yield
- sql多表查询的总结
- 点击某些按钮不要触发验证控件
- 深入理解Solaris内核中互斥锁(mutex)与条件变量(condvar)之协同工作原理
- Flash 二进制传图片到后台Java服务器接收
- DRILLNET 2.0------第八章 预防碰撞分析模型
- 使用dime传输大附件的设置(WSE Soap toolkit)
- python+selenium+unittest测试框架3-项目构建和发送邮件
- [BZOJ2850]巧克力王国
- 多态与异常处理——动手动脑