题目地址:

https://www.acwing.com/problem/content/489/

金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NNN元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有000个、111个或222个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的NNN元。于是,他把每件物品规定了一个重要度,分为555等:用整数1∼51\sim 51∼5表示,第555等最重要。他还从因特网上查到了每件物品的价格(都是101010元的整数倍)。他希望在不超过NNN元(可以等于NNN元)的前提下,使每件物品的价格与重要度的乘积的总和最大。设第jjj件物品的价格为v[j]v[j]v[j],重要度为w[j]w[j]w[j],共选中了kkk件物品,编号依次为j1,j2,…,jkj_1,j_2,…,j_kj1​,j2​,…,jk​,则所求的总和为:v[j1]∗w[j1]+v[j2]∗w[j2]+…+v[jk]∗w[jk]v[j_1]∗w[j_1]+v[j_2]∗w[j_2]+…+v[j_k]∗w[j_k]v[j1​]∗w[j1​]+v[j2​]∗w[j2​]+…+v[jk​]∗w[jk​](其中∗*∗为乘号)请你帮助金明设计一个满足要求的购物单。

输入格式:
输入文件的第111行,为两个正整数,用一个空格隔开:NmN\ mN m,其中NNN表示总钱数,mmm为希望购买物品的个数。从第222行到第m+1m+1m+1行,第jjj行给出了编号为j−1j-1j−1的物品的基本数据,每行有333个非负整数v,p,qv, p, qv,p,q,其中vvv表示该物品的价格,ppp表示该物品的重要度(1∼51\sim 51∼5),qqq表示该物品是主件还是附件。如果q=0q=0q=0,表示该物品为主件,如果q>0q>0q>0,表示该物品为附件,qqq是所属主件的编号(指的是第一次遇到这个主件的时候的计数,从111开始数)。

输出格式:
输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<200000<200000<200000)。

数据范围:
N<32000,m<60,v<10000N<32000,m<60,v<10000N<32000,m<60,v<10000

更好的做法参考https://blog.csdn.net/qq_46105170/article/details/125026481。

可以看成是分组背包问题,每个物品体积就是viv_ivi​,价值就是vi×piv_i\times p_ivi​×pi​。每个主件及其所有附件打包成一起看成一组,每组的选择是,可以买其主件与附件的任意搭配(比如其有uuu个附件,那么搭配的方案数就是2u2^u2u种)。用动态规划来做即可,设f[i][j]f[i][j]f[i][j]是只考虑前iii组物品的情况下,总成本不超过jjj时的最大价值,那么可以按照第iii组选哪个来分类(这里的“选哪个”包含第iii组物品的所有搭配,比如不选第iii组,只选主件,只选主件和第一附件,等等),如果不选,那么最大价值就是f[i−1][j]f[i-1][j]f[i−1][j],如果选,那么最大价值就是f[i−1][j−vi]+vi×pif[i-1][j-v_i]+v_i\times p_if[i−1][j−vi​]+vi​×pi​(这里要遍历所有附件的搭配情况),两者取大即可。代码如下:

#include <iostream>
#include <vector>
using namespace std;typedef pair<int, int> PII;const int N = 70, M = 32010;int n, m;
// 存主件的价格和收益
PII master[N];
// servant[i]存i号主件的价格和收益
vector<PII> servant[N];
int f[M];int main() {cin >> m >> n;for (int i = 1; i <= n; i++) {int v, w, q;cin >> v >> w >> q;// q是0的话,当前物品是主件if (!q) master[i] = {v, v * w};// 否则是附件,价格是v,收益是v * welse servant[q].push_back({v, v * w});}for (int i = 1; i <= n; i++) // 这是0-1背包问题,体积要从大到小遍历for (int j = m; j >= 0; j--) {auto &sv = servant[i];// 枚举所有附件的搭配情况,用状态压缩的办法枚举for (int k = 0; k < 1 << sv.size(); k++) {int v = master[i].first, w = master[i].second;for (int u = 0; u < sv.size(); u++)if (k >> u & 1) {v += sv[u].first;w += sv[u].second;}if (j >= v) f[j] = max(f[j], f[j - v] + w);}}cout << f[m] << endl;return 0;
}

时间复杂度O(Nm)O(Nm)O(Nm),空间O(m)O(m)O(m)。

【ACWing】487. 金明的预算方案相关推荐

  1. AcWing 487. 金明的预算方案 (有依赖关系的背包问题)

    题意 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间. 更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就 ...

  2. AcWing 487. 金明的预算方案

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间. 更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行&q ...

  3. 487 金明的预算方案(分组背包问题扩展)

    1. 问题描述: 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置,你说了算,只要不超 ...

  4. 【每日DP】day7P1064 金明的预算方案 (分组背包,我又悟了)难度⭐⭐★

    P1064 金明的预算方案 背包其实就是把一个大问题拆分成若干个子问题,把一个要拿东西的动作按照题目要求分成若干个动作,分别枚举(DP其实就是非常的暴力),比较取最大值. 比如这道题,背包的物品之间是 ...

  5. P1064 金明的预算方案

    P1064 金明的预算方案 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:"你的房间需要购买哪些物品,怎么布置 ...

  6. [LuoguP1064][Noip2006]金明的预算方案

    金明的预算方案(Link) 题目描述 现在有\(M\)个物品,每一个物品有一个钱数和重要度,并且有一个\(Q\),如果\(Q = 0\),那么该物件可以单独购买,当\(Q != 0\)时,表示若要购买 ...

  7. P1064 [NOIP2006 提高组] 金明的预算方案

    P1064 [NOIP2006 提高组] 金明的预算方案 题意: 每个物品有价格和价值,物品之间存在依赖关系(单向的),现在又n元钱,买哪些物品,即满足依赖关系又使得每件物品的价格与价值的乘积的总和最 ...

  8. 不止代码:洛谷P1064 金明的预算方案+P2014选课(依赖背包)

    文章目录 题目描述 总结 解析 解法1 解法2 代码 解法3 代码 题目描述 金明的预算方案 选课 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是, ...

  9. 背包形动态规划 fjutoj2375 金明的预算方案

    金明的预算方案 TimeLimit:1000MS  MemoryLimit:128MB 64-bit integer IO format:%lld Problem Description 金明今天很开 ...

最新文章

  1. mysql之基础操作grant、show、repair、log_error等
  2. JavaScript夯实基础系列(二):闭包
  3. java应用高内存占用
  4. JavaScript自执行匿名函数
  5. php 识别图片主色调,PHP 判断图片主色调的简单示例
  6. centOS 7镜像文件下载
  7. 基于双麦克风声源定位的视频跟踪
  8. 合作开发过程产生的专利_合作开发合同(二)
  9. svn--Eclipse版本的安装步骤
  10. CentOS系统里如何正确取消或者延长屏幕保护自动锁屏功能(图文详解)
  11. [译] 为什么给设计定义 UX、UI、CX、IA、IxD 和其他类型的头衔是愚蠢的行为
  12. ISA 对比 PCI(ISA vs PCI)
  13. fseek函数的用法
  14. 软件开发常见的开发方向
  15. 高数_第3章重积分_在柱面坐标下计算三重积分
  16. MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)
  17. 开发了一款微信拜年小程序
  18. 物联网技术概论:第1章
  19. SVG代码如何转为SVG文件
  20. 5-3 外星人颜色#1

热门文章

  1. Vue # Avoid mutating a prop directly since the value will be overwritten wheneve
  2. 数据链路层——局域网扩展
  3. 判断输入的手机号码格式是否正确(用Java实现)
  4. 安装 Ubuntu 22.04.1 LTS 桌面版(详细步骤)
  5. illumina平台的测序接头
  6. 宝宝起名神器小程序源码_支持多种流量主模式
  7. micropython stm32f107_stm32f107 USART3数据接收错误问题
  8. jar 坐标系转换工具_MODIS数据处理工具HEG安装教程
  9. 原生JS活动倒计时实现思路
  10. dw改透明度_div 背景透明度 如何设置一个div的背景透明度