动态规划——01背包问题 看此一篇文章就够了
本文讲述经典算法——动态规划的 常见问题 01背包
一篇文章带你学会01背包问题,妈妈再也不担心我遇到01背包了!!!
问题描述
有n个物品,它们有各自的体积和价值,现有给定容量m的背包,如何让背包里装入的物品具有最大的价值总和?
每种物品只有放入和不放入这两种状态,因此叫做01背包问题
为方便讲解和理解,下面讲述的例子均先用具体的数字代入,即:eg:n=4,m=6
i(物品编号) | 1 | 2 | 3 | 4 |
w(体积) | 1 | 2 | 3 | 2 |
v(价值) | 4 | 6 | 12 | 7 |
由于样例数据量小,我们很容易可以看出来最优的选择为物品3+物品4+物品1
总重量=3+2+1=6 总价值=12+7+4=23 这就是最优解;
有的人可能会有疑惑,可以用贪心吗? 答案是 不可以;
因为选取单个价值最高并不能保证最终的总价值是最高的,也许有一个体积比它小很多,价值相差不大的呢,这样不就没选它了嘛。
动态规划问题的本质
本质就是穷举?递归?递推?
Q1:如何穷举?
写出状态转移方程,暴力穷举所有可行解。
Q2:如何聪明地穷举?
用备忘录消除重叠子问题,写出自顶向下的解法;
进一步,可以写出自底向上的迭代递推的解法;
再进一步,可能可以优化空间复杂度
动态规划问题的解题思路分析
1、通过问题描述,时间状态、选择、定义这几部框架
2、写状态状态转移方程
3、一眼看出是否存在重叠子问题
4、确定dp数组的遍历顺序
针对该问题,我们来看一看具体的步骤是怎样的。
根据第一步 状态有:装入物品数量、背包容量,所以确定我们的dp数组是二维的
一定要清楚的明白dp数组代表的含义,才能顺利地写出状态转移方程!这一点很重要!!!
首先看第二个情况,不把物品放进背包的最大价值
不放第 i 个物品,不就意味着,最大价值就等于 前 i-1个物品的最大价值嘛
所以 dp[i][w] = dp[i - 1][w];
--------------------------------------------------------------------------------------------------------------------
然后再看比较复杂一点的第一种情况,将物品放进背包的最大价值
这种情况下,我们存放结果情况显然不变,依然是i个物品放w容量,所以前面还是dp[i][w]
那么=后面的结果呢?
就是前面 i-1 个物品,在容量为 w-当前物品重量的情况下 ,加上 第 i 件物品的价值!悟了吧
所以 dp[i][w] = dp[i - 1][w - wp[i].wei] + wp[i].val;
----------------------------------------------------------------------------------------------------------------------
然后,我们应该分情况,当该物品能够被放进去才进行计算
否则就和没有放入的结果一样。
相信你看到这里已经很有感触了,我们来看看代码是怎么实现的吧。
#include<bits/stdc++.h>
using namespace std;
struct wupin{int wei;int val;
}wp[3405];
int dp[3500][13000];
int main(){int n,m; //n种物品,容量mcin>>n>>m;for(int i = 1;i <= n;i++) cin>>wp[i].wei>>wp[i].val;for(int i = 1;i <= n;i++){ // i 代表 前i个物品for(int j = 1;j <= m;j++){ // j 代表 背包容量为 j 时if(wp[i].wei > j){dp[i][j] = dp[i-1][j];}else{dp[i][j] = max(dp[i-1][j], dp[i-1][j-wp[i].wei] + wp[i].val);}}}cout<<dp[n][m]<<endl;return 0;
}
结合上述思路,是不是已经理解了呢?
这里有一个问题,就是当数据量比较大时,比如代码中的n=3500,m=13000时,会消耗巨大的内存,大概是180MB,这会超过大多数OJ的内存限制,比如 北大OJ(POJ 4131) ,用上述代码就超过内存限制了!
如何解决这一问题呢?
在这里我们使用滚动数组的方式就可以解决了!
这里给出代码,稍有不同的是,该题滚动数组方式采用从右往左的顺序求值
#include<bits/stdc++.h>
using namespace std;
struct wupin{int wei;int val;
}wp[3405];
int dp[13000]={0};
int main(){int n,m; //n种物品,容量mcin>>n>>m;for(int i=1;i<=n;i++)cin>>wp[i].wei>>wp[i].val;for(int i=1;i<=n;i++){ // i 代表 前i个物品for(int j=m;j>=0;j--){ // j 代表 背包容量为 j 时if(wp[i].wei<=j){dp[j] = max(dp[j],dp[j-wp[i].wei]+wp[i].val);}}}cout<<dp[m]<<endl;return 0;
}
这样代码就AC啦!!!
至此,01背包问题已经讲述完了,如果有什么不明白的地方或是文章存在一些问题,欢迎coder在下方留言。
动态规划——01背包问题 看此一篇文章就够了相关推荐
- js层级选择框样式_IOS和JS的交互,看这一篇文章就够了
IOS和JS的交互,看这一篇文章就够了 创作不易,请珍惜,之后会持续更新,不断完善 Demo地址 目录 WKWebView使用.JS的交互 WKWebView使用.JS的交互 演示(本来想贴张GIF作 ...
- 关于VR产品的前世今生,看这一篇文章就够了
关于VR产品的前世今生,看这一篇文章就够了(转) 文/胡勇 即使最富质疑精神最冷静的人也无法漠视现在的 VR/AR 掀起的狂潮,这个从科技圈蔓延到实业界最后席卷大众的想象力的狂欢正以前所未有的态势改变 ...
- 五年程序员是如何玩转闲鱼无货源的,只看这一篇文章就够了
今天的内容方向主要是基础篇-进阶篇 ,优化了一下操作方法,尽量细化,让你看完这篇内容之后从入门到大神. 基础篇: 注册这些基础的之前说过,这次就不说了,这次说下如何养号. 完善个人资料(头像.昵称.简 ...
- 产品经理如何进行数据分析?看这一篇文章就够了
一.数据分析的层级 产品的数据分析经常会遇到这样的问题:只有数据,没有分析.仅仅是描述数据,告诉你产品发生了什么. 比如次日留存率只有5%,这个数据偏低,可以看出该功能的用户粘性不好. 然后呢?往往就 ...
- 如何进行云主机迁移?看这一篇文章就够了!
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云计算产品团队发表于云+社区专栏 主机迁移概述 在云计算时代,不管是从IDC上云还是多云直接的迁移,都已经是常见的事宜.而在上云/ ...
- java 计算机概述看这一篇文章就够了
第一章 计算机概述 第1节 计算机介绍 1 广义上: 凡是可以帮助我们完成计算的工具统称为计算机(比如 算盘.计算器等...) 狭义上: 当前说计算机一般情况特指电子计算机(电脑) 第2节 计算机历史 ...
- 关于5G,看这一篇文章就够了
对于大多数人来说,5G 这个名词即使不了解也一定听说过.不过,4G 时代不是才开始没几年吗?现在就说下一代无线通讯技术是不是有点早?确实是,不过时光飞逝岁月如梭,技术发展可不等人,5G移动通信可能很快 ...
- scrapy框架_入门Scrapy框架看这一篇文章就够了
前言 Scrapy是一个非常优秀的框架,操作简单,拓展方便,是比较流行的爬虫解决方案. Scrapy是一个用Python写的Crawer Framework,简单轻巧而且非常方便.Scrapy使用Tw ...
- 什么是Docker?看这一篇文章就够了
作者 | 码农的荒岛求生 来源 | 程序员小灰(ID: chengxuyuanxiaohui) 程序员,应该怎样理解docker? 容器技术的起源 假设你们公司正在秘密研发下一个"今日头条& ...
最新文章
- 选择时间日历控件DatePickerDialog实现(从外包项目中挖出来整理的)
- 【结论】【dfs】费解的开关(joyoi-tyvj 1266)
- [html] html如何创建图片热区(img usemap)?
- 去除标题_资深运营导师-云中教你轻松写标题
- 字符串去重_文件数据去重示例
- android天气预报----google开源天气API,SAX解析
- Lnixu Bash
- Mysql中Regexp常见用法
- matlab怎么取差分,差分进化算法原理与matlab实现
- 一次由于SQL Server BUG引起的数据库AlwaysOn主从切换故障分析处理
- css 超出文字头尾相接滚动_【转载】CSS3 ——文本超出设置 超出显示...与跑马灯效果...
- 《惢客创业日记》2019.11.28(周四)近者悦,远者来
- 绝地腾讯手游登入显示服务器满了,绝地求生刺激战场注册已满什么意思 注册已满解决方法详解[多图]...
- 百度地图显示坐标读取服务器数据,借助百度地图api解决获取经纬坐标问题
- 使用HTML5制作的网页游戏-管道小鸟(附源码)
- 计算机专业英文简历 样本,本科生简历:计算机专业优秀本科生英文简历样本供参考.docx...
- VBA实战(11) - 工作表(Sheet) 操作汇总
- 怎样设计才能让文字排版更好看(三)
- python珠穆朗玛峰问题_学会这6招,让你的Python 嗖嗖嗖的快!
- 云上PDF怎么删除页眉页脚_怎么删除PDF文档中多余的页面
热门文章
- VSS(Visual SourceSafe) 代码管理器 使用技巧---快速登录
- 体验Microsoft Expression Blend 3 Preview
- 项目中的集中开发模型研究
- 领域驱动 开源项目_在开源领域建立职业的建议
- 程序开源与不开源区别_什么是开源程序办公室? 为什么需要一个?
- vulkan api_Vulkan开放标准API支持,针对Linux的新游戏以及更多游戏
- 2019年南大计算机开放日_开放式硬件计算机年
- (49)移动端开发之流式布局(百分比布局)
- es6 Symbol.for(),Symbol.keyFor()
- 手动抛出异常_(七)异常处理