王道机试 第十二章 动态规划 12.5 背包问题

1、0-1背包

0-1背包的关键特点:每种物品至多选一次,即要么选1个要么不选(0/1次)

例题12.7 点菜问题(北京大学复试上机题)
  • 题目分析
    本题涉及到要么选,要么不选,且价值最大的问题,故而为0-1背包问题。
  • 注意事项
  • 背包数组的范围——和容量C相关,定义maxm=C+5
  • 内层循环倒序
    原因:
    0-1背包问题的原始DP方程为dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]+v[i]])dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i] + v[i]])dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]+v[i]])。由此可知,在第iii轮更新dp[i][j]dp[i][j]dp[i][j]时,使用的是第i−1i - 1i−1轮的dp[i−1][j−w[i]]dp[i - 1][j - w[i]]dp[i−1][j−w[i]]的数值。即:在第iii轮必须先更新dp[i][j]dp[i][j]dp[i][j],然后才轮到dp[i−1][j−w[i]]dp[i - 1][j - w[i]]dp[i−1][j−w[i]]更新,因此必须让jjj倒序递减循环,以保障更新顺序

0-1背包问题的C++核心代码如下:

  • 初始化:
const int maxm = 1005; // 背包容量+5
int dp[maxm]; // dp数组
memset(dp, 0, sizeof(dp)); // 初始值
  • 递推(内层循环倒序):
for (int i = 1; i <= n; i++){for (int j = C; j >= w[i]; j--){dp[j] = max(dp[j], dp[j - w[i]] + v[i]);}}
  • 结果输出
cout << dp[C] << endl; // C为背包容量

本问题的完整C++代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;const int maxn = 105;
const int maxm = 1005;
int dp[maxm];
int w[maxn], v[maxn]; // 重量,价值int main()
{int C, n;while (cin >> C >> n){memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; i++){cin >> w[i] >> v[i];}for (int i = 1; i <= n; i++){for (int j = C; j >= w[i]; j--){dp[j] = max(dp[j], dp[j - w[i]] + v[i]);}}cout << dp[C] << endl;} return 0;
}
例题12.7 点菜问题(北京大学复试上机题)
  • 题目解读
  • 板子题,涉及要么选要么不选的问题,容量固定使得价值最大。0-1背包问题。

C++代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;const int maxn = 105;
int w[maxn], v[maxn]; // weight, valueconst int maxm = 1005;
int dp[maxm];int main()
{int C, n;while (cin >> C >> n){memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; i++){cin >> w[i] >> v[i]; // time, value}for (int i = 1; i <= n; i++){for (int j = C; j >= w[i]; j--){dp[j] = max(dp[j], dp[j - w[i]] + v[i]);}}cout << dp[C] << endl; }return 0;
}
习题12.6 最小邮票数(清华大学复试上机题)
  • 转化为0-1背包:
    每个物品价值为1,令dp[j]dp[j]dp[j]表示凑齐jjj元所需要的最少邮票数。则有:
    dp[j]=min(dp[j−w[i]]+1,dp[j])dp[j] = min(dp[j - w[i]] + 1, dp[j])dp[j]=min(dp[j−w[i]]+1,dp[j]),如果dp[j−w[i]]!=infdp[j - w[i]] != infdp[j−w[i]]!=inf,即方案数存在。
  • 初始值:
    凑齐0元所需货币数为0,其余为inf

C++代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;const int maxn = 25;
int w[maxn], v[maxn];const int maxm = 105;
int dp[maxm];int main()
{int inf = 0x3f3f3f3f;int m, n;fill(v, v + maxn, 1); // 初值while (cin >> m >> n){for (int i = 1; i <= n; i++){cin >> w[i];}for (int i = 1; i <= m; i++){dp[i] = inf; // 初始值}dp[0] = 0; // 初始值for (int i = 1; i <= n; i++){for (int j = m; j >= w[i]; j--){if (dp[j - w[i]] != inf) dp[j] = min(dp[j], dp[j - w[i]] + v[i]);}}if (dp[m] == inf) cout << 0 << endl;else cout << dp[m] << endl;}return 0;
}
Piggy Bank
  • 最后的输出有英文句号!!!
  • 题目解读
  • 完全背包问题,有nnn种物品,可以取多次,每种物品重量为w[i]w[i]w[i],价值为v[i]v[i]v[i],问如何放置使得在背包完全被装满的情况下,价值最小。

C++代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;const int maxm = 100005;
const int maxn = 505;long long dp[maxm];
int w[maxn], v[maxn];int main()
{int t; cin >> t;int inf = 0x3f3f3f3f;while (t--){int e, f, C;cin >> e >> f;C = f - e;if (C < 0){cout << "This is impossible.\n";continue;}int n; cin >> n;for (int i = 1; i <= n; i++){cin >> v[i] >> w[i];}for (int i = 1; i <= C; i++){dp[i] = inf;}dp[0] = 0;for (int i = 1; i <= n; i++){for (int j = w[i]; j <= C; j++){if (dp[j - w[i]] != inf) dp[j] = min(dp[j], dp[j - w[i]] + v[i]);}}if (dp[C] >= inf) cout << "This is impossible.\n";else cout << "The minimum amount of money in the piggy-bank is " << dp[C] << "." << endl;}return 0;
}

王道机试 第十二章 动态规划 12.5 背包问题(0-1背包,完全背包,多重背包)相关推荐

  1. 机试指南第七章-动态规划-笔记及背包问题

    第七章     动态规划 一.递归求解: 递归问题的关键是解决初始值和递推公式,从而将复杂问题分解为简单问题直至初始值对应的极简问题,从而得到答案. 套路:初始值+递归公式. Trick:将求出的值存 ...

  2. 《汇编语言》王爽(第四版) 第十二章 实验12

    文章目录 前言 一.思路分析 1.安装 2.设置中断向量 3.do0程序 4.测试 5.优化 二.最终成果 1.完整代码 2.效果图 总结 前言 本文是王爽老师<汇编语言>(第四版) 第十 ...

  3. 高数第十二章 级数12.1 常数项级数

    常数项级数 级数的分类 级数收敛 数项级数 函数项级数 常数项级数 性质 两个重要级数 正向级数 正项级数审敛法 交错级数 莱布尼茨审敛法 绝对收敛与条件收敛 常数项级数审敛法 级数的分类 一. 1. ...

  4. Java课后题第十二章:12.18(添加包语句)

    1.找到文件路径 File file = new File("D:\\PackageP13\\");File[] files = file.listFiles(); 2.复制到St ...

  5. 第十二章 Openwrt无法识别2.0 USB 盘

    今天新的U盘不能识别,还以为是U盘本身的问题,原来是缺少 kmod-usb-storage kmod-usb-storage-extras 这两个软件包. 软件包安装后重启便可识别. 转载于:http ...

  6. 第十二章 支持向量机-机器学习老师板书-斯坦福吴恩达教授

    第十二章 支持向量机 12.1 优化对象 12.2 大间隔的直观理解 12.3 大间隔分类器的数学原理 12.4 核函数一 12.5 核函数二 12.6 使用SVM 12.1 优化对象 12.2 大间 ...

  7. Android群英传读书笔记——第十二章:Android 5.X新特性详解

    第十二章目录 12.1 Android5.X UI设计初步 12.1.1 材料的形态模拟 12.1.2 更加真实的动画 12.1.3 大色块的使用 12.2 Material Design主题 12. ...

  8. 鸟哥的Linux私房菜(服务器)- 第十二章、网络参数控管者: DHCP 服务器

    第十二章.网络参数控管者: DHCP 服务器 最近更新日期:2011/07/27 想象两种情况:(1)如果你在工作单位使用的是笔记本电脑,而且常常要带着你的笔记本电脑到处跑, 那么由第四章.连上 In ...

  9. 鸟哥的Linux私房菜(服务器)- 第二十二章、邮件服务器: Postfix

    第二十二章.邮件服务器: Postfix 最近更新日期:2011/08/10 在这个邮件服务器的架设中,我们首先谈论 Mail 与 DNS 的重要相关性,然后依序介绍 Mail Server 的相关名 ...

  10. stm32l0的停止模式怎么唤醒_探索者 STM32F407 开发板资料连载第二十二章 待机唤醒实验

    1)实验平台:alientek 阿波罗 STM32F767 开发板 2)摘自<STM32F7 开发指南(HAL 库版)>关注官方微信号公众号,获取更多资料:正点原子 第二十二章 待机唤醒实 ...

最新文章

  1. mysql 高效备份_Mysql高性能备份方案解决数据不间断访问(LVM快照方式备份)
  2. NYOJ 12 喷水装置(二)
  3. Windows 窗体设计器中的设计时错误
  4. 异常空格,ASCII (194,160)问题
  5. 使用jQuery实现图片懒加载原理
  6. android viewpager fragment传值,Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题...
  7. 问题 B: 十进制到二进制的转换
  8. xadmin 显示外键字段
  9. 财政部:瑞幸咖啡虚增收入21.19亿元 虚增利润9.08亿元
  10. Ubuntu 修改Apache2网站根目录及默认网页
  11. Mysql导出数据 (windows Linux)
  12. Vue阿里云物流API
  13. TiDB错误码与故障排除
  14. 华为od python_华为运维开发-华为OD工资待遇怎么样 - 华为技术有限公司 - 职友集...
  15. 记事本html表白,霸道总裁之代码强势表白
  16. “小而美”走到十字路口,吉利或收购魅族助车机闭环
  17. 解读中国版新资本协议
  18. 英语单词 One 个人 5. 身体动作
  19. golang 单元测试进阶篇
  20. 轻松解决mscorsvw.exe进程CPU占用高的问题

热门文章

  1. 手机变速齿轮_变速齿轮手机版下载|变速齿轮游戏加速器官方最新版v1.2下载 _当游网...
  2. [lua]紫猫lua教程-命令宝典-L1-03-01. 闭包
  3. 百度坐标转换中文地址(百度地图JavaScript API逆地址解析 )
  4. 詹克团:《区块链:人类劳动组织的未来形式》
  5. linux可以用tab键,linux下tab键在命令行情况下的强大
  6. 基于蒙特卡洛的大规模电动汽车充电行为分析(Matlab代码实现)
  7. 101个最佳配色方案,设计师值得收藏!
  8. PPT 配色-颜色代码
  9. Node.js环境搭建
  10. android 外接扫码枪_Android设备获取扫码枪扫描的内容与可能遇到的问题解决