01背包问题动态规划(二维数组)
01背包问题动态规划(二维数组)
问题描述
一个旅行者有一个最多能装 M 公斤的背包,现在有 n 件物品,它们的重量分别是W1,W2,…,Wn,它们的价值分别为C1,C2,…,Cn,求旅行者能获得最大总价值。
输入格式
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);
第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
10 4
2 1
3 3
4 5
7 9
输出格式
仅一行,一个数,表示最大总价值。
12
代码
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <string.h>int main()
{int M, N; // M(背包容量,M<=200)和N(物品数量,N<=30);std::cin >> M >> N;int dp[N + 1][M + 1];// dp数组初始化全部 0;for (int i = 0; i < N + 1; i++)for (int j = 0; j < M + 1; j++)dp[i][j] = 0;int Wi[N + 1] = {0};int Ci[N + 1] = {0};memset(Wi, 0, sizeof(Wi));memset(Ci, 0, sizeof(Ci));for (int i = 1; i < N + 1; i++){std::cin >> Wi[i] >> Ci[i];}/* for (int i = 0; i < N + 1; i++){std::cout << Wi[i] << Ci[i] << std::endl;} */for(int i=1; i<N+1; i++){for(int j=1; j<M+1; j++){if(j >= Wi[i]) // 如果可以装下{dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-Wi[i]]+Ci[i]);}else // 装不下{dp[i][j] = dp[i-1][j];}}}for(int i=0; i<N+1; i++){for(int j=0; j<M+1; j++){std::cout << dp[i][j] << " ";}std::cout << std::endl;}std::cout << dp[N][M] ;return 0;
}
总结
1.构造二维dp数组 dp[N+1][M+1]
,N是物品编号,M是背包重量。
2.边界dp[0][M+1]
dp[N+1][0]
全部初始化为0
;
3.背包重量优先遍历(先从左到右,然后上到下)
for(int i=1; i<N+1; i++){for(int j=1; j<M+1; j++){if(j >= Wi[i]) // 如果可以装下{dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-Wi[i]]+Ci[i]);}else // 装不下{dp[i][j] = dp[i-1][j];}}}
4.遍历有两种情况
if(j >= Wi[i]) // 如果可以装下
{
dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-Wi[i]]+Ci[i]);
}
else // 装不下
{
dp[i][j] = dp[i-1][j];
}
如果装不下当前物品:
那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样的。
dp[i][j] = dp[i-1][j];
如果装得下当前物品:
假设1:装当前物品,在给当前物品预留了相应空间的情况下,前n-1个物品的最佳组合加上当前物品的价值就是总价值。
假设2:不装当前物品,那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样的。
选取假设1和假设2中较大的价值,为当前最佳组合的价值。
dp[i][j] = std::max(dp[i-1][j], dp[i-1][j-Wi[i]]+Ci[i]);
4.最后dp[N][M]
就是问题的答案
01背包问题动态规划(二维数组)相关推荐
- 完全背包问题(二维数组)
通过三天的发文章,终于稍微弄明白MarkdownMarkdownMarkdown了,接下来话不多说,直接干正事. 前两篇文章分别和大家讲了一下01背包的两种做法,感兴趣的可以去看看. 今天和大家分享一 ...
- hdu1176 免费馅饼 动态规划 二维数组实现
免费馅饼 Time Limit: 1000MS Memory Limit: 32768KB Submit Statistic Discuss Problem Description 都说天上不会掉馅饼 ...
- 动态规划 -- 二维数组中左上到右下的最短路径和。
目录 问题: 应用场景: 分析: C++实现 问题: 给定一个二维数组map[4][4] ={{1,3,5,9},{8,1,3,4},{5,0,6,1},{8,8,4,0}}.求从左上角到右下角的最短 ...
- 01背包和完全背包 的完整讲解版 包含 一维数组实现 和二维数组实现题目
(二)01背包和完全背包 的完整讲解版 包含 一维数组实现 和二维数组实现题目 //有N件物品和一个容量为V的背包.第i件物品的体积是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. ...
- Python如何创建二维数组和初始化
一.Python用什么表达二维数组 严格意义上说,Python中并没有数组的概念,Python中表达一组数据有多种形式,例如list,tuple,set等数据结构都可以表达一组数,并且这组数也没有C和 ...
- 问题 A: 【动态规划】采药_二维数组_一维数组
问题 A: [动态规划]采药 时间限制: 1 Sec 内存限制: 64 MB 提交: 35 解决: 15 [提交][状态][讨论版] 题目描述 山洞里有一些不同的草药,采每一株都需要一些时间,每一 ...
- HDU 2159 FATE 动态规划二维费用的背包问题
http://acm.hdu.edu.cn/showproblem.php?pid=2159 题意: 给出的n , m , k ,s 分别代表还需n经验升级.还有m耐久度.下面有k组数据.最多能杀s只 ...
- NOJ--宠物小精灵之收服(01背包,二维费用背包问题)
宠物小精灵之收服 1000ms 65536K Description: 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事. 一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵 ...
- 剑指Offer #01 二维数组中的查找(Java描述)
题目来源:牛客网-剑指Offer专题 题目地址:二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一 ...
最新文章
- mysql right join实例_MySQL表LEFT JOIN左连接与RIGHT JOIN右连接的实例教程
- android Unable to add window -- token null is n...
- Streaming源码解读之接收流数据的全生命周期
- python开发面试题目_Python测试开发面试笔试题
- 1104冒泡排序语法树
- 洛谷P1311 选择客栈
- 关于linux的进程和线程
- 检测到目标url存在内部ip地址泄露_Cendertron,动态爬虫与敏感信息泄露检测
- 服务器部署Nodejs api 接口
- 关于面试总结6-SQL经典面试题
- ACE认证考试—阿里云产品概念深化学习
- 看完知乎轮子哥的编程之路,我只想说,收下我的膝盖。。。
- git 操作报错(fatal: ‘xxx’ does not appear to be a git repository)
- 【数字电子技术基础】数字电子钟设计
- PPT中插入avi、mpg、flv、swf及rm、rmvb等视频文件的方法
- vue2中vant实现网易云音乐案例-附带所有源码
- opencv+hough直线检测+fitline直线拟合
- mysql8.0.13解压版安装密码设置_mysql8.0.13解压版安装配置方法图文教程
- 笔记本电脑右下角的电池图标不显示如何找出
- Pytorch踩坑记之交叉熵(nn.CrossEntropy,nn.NLLLoss,nn.BCELoss的区别和使用)
热门文章
- 直播为什么这么火?---Live内容记录
- Android实战简易教程-第五十一枪(ListView实现子控件的动态显示和隐藏、checkbox全选和反选)
- 超级炫酷的AI绘图工具—MidJourney详细使用教程
- 巴厘岛上航直飞3N5D行程
- 报错: Err:8 http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu xenial Release.gpg The following signatur
- 软件工程(二)软件生存周期与软件过程
- html5 canvas基础与动画开发详解-吴华-专题视频课程
- 计算机思维导论第二讲答案,大学计算机计算思维导论第2讲习题及解析.pdf
- AS3连连看源码教程(三)
- linux下的命令行词典