算法提高 金明的预算方案  
时间限制:1.0s   内存限制:256.0MB
    
问题描述
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅

  如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是10元的整数倍)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
  设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j_1,j_2,……,j_k,则所求的总和为:
  v[j_1]*w[j_1]+v[j_2]*w[j_2]+ …+v[j_k]*w[j_k]。(其中*为乘号)
  请你帮助金明设计一个满足要求的购物单。

输入格式
输入文件budget.in 的第1行,为两个正整数,用一个空格隔开:
  N m
  (其中N(<32000)表示总钱数,m(<60)为希望购买物品的个数。)
  从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有3个非负整数
  v p q
  (其中v表示该物品的价格(v<10000),p表示该物品的重要度(1~5),q表示该物品是主件还是附件。如果q=0,表示该物品为主件,如果q>0,表示该物品为附件,q是所属主件的编号)
输出格式
输出文件budget.out只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<200000)。
样例输入
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
样例输出
2200
问题分析:这道题看到网上大牛有一个很好的解析,在这里借鉴一下
此题是01背包问题的变形。物品的重要度乘以价格是背包问题中的价值,物品的价格是背包问题中的体积。
1、我们可以把如何在众多主件与附件之中选择购买的问题转变为看成购买的5种方案:
  (1)什么都不买,(2)只买主件,(3)买主件和附件1,(4)买主件和附件2,(5)买主件和两个附件。
2、有些主件有附件,而有些没有,这为我们思考带来了负担,我们完全可以假设任何主件都有两个附件,也就是说如果题目没有给出某个主件的附件的话,我们就假设这个主件的附件是存在的,且价格和重要度都等于0。这个假设首先不会影响到程序的正确性,也不会增加多少运算时间,且这种假设使得我们想问题和写程序都变得简单多了。
3、题目中的价格都是10的这个条件,可以减少一些时间和空间的开销。
    此题和01背包问题有2个主要的区别:
    区别一:01背包问题对当前物品考虑的只有买和不买两种情况,而此题需要考虑上面所说的5种不同的购买方案。 
    区别二:01背包问题是用v[i]来保存第i个物品的价值,而此题需要用v[i]来保存第i个物品和它的两个附件的价值,此时我们需要二维数组来实现,物品体积w同样需要用二维数组来保存。
     v[i][0]表示第i个物品的主件价值, v[i][1]表示第i个物品的第一个附件的价值,v[i][2]表示第i个物品的第二个附件的价值 .w[i][0..2]表示同样的物品的体积。
     f[i,j]表示给定i个物品和j的空间能够获得的最大价值总合。
 则:
f[i,j]=max{f[i-1,j],
           f[i-1,j-w[i,0]]+v[i,0],
           f[i-1,j-w[i,0]-w[i,1]]+v[i,0]+v[i,1],
           f[i-1,j-w[i,0]-w[i,2]]+v[i,0]+v[i,2],
           f[i-1,j-w[i,0]-w[i,1]-w[i,2]]+v[i,0]+v[i,1]+v[i,2]}
   其实,此题还有一个关键点,就是输入数据的处理。
    根据题目的意思,q是物品的编号,但是这个编号是在考虑附件时统计的编号,而我们认为附件和主件是一体的,因此附件编号因该和主件一致,所以我们需要对题目给出的编号进行转换。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;const int maxn = 40000;
int f[70][maxn];
int value[70][3],imp[70][3];int main()
{int n,m;int v,p,q;scanf("%d%d",&n,&m); for(int i=1; i<=m; i++){scanf("%d%d%d",&v,&p,&q);//为主件 if (!q){value[i][0] = v;imp[i][0] = p;}//为附件 else{if (!value[q][1]){value[q][1] = v;imp[q][1] = p;}else{value[q][2] = v;imp[q][2] = p;}}}   memset(f,0,sizeof(f)); for(int i=1; i<=m; i++){for(int j=1; j<=n; j++){if (j-value[i][0]>=0){//仅主件 f[i][j] = max(f[i-1][j],f[i-1][j-value[i][0]] + value[i][0]*imp[i][0]);//这个时候的f[i][j]表示仅有主件的时候的情况,而下面每种加附件的情况,都是在有主件的基础下,所以//直接和f[i][j]比较 //主件 + 附件1 if (j-value[i][0]-value[i][1]>=0)f[i][j] = max(f[i][j],f[i-1][j-value[i][0]-value[i][1]] + value[i][0]*imp[i][0] + value[i][1]*imp[i][1]);//主件 + 附件2 if (j-value[i][0]-value[i][2]>=0)f[i][j] = max(f[i][j],f[i-1][j-value[i][0]-value[i][2]] + value[i][0]*imp[i][0] + value[i][2]*imp[i][2]);//主件 + 所有附件if (j-value[i][0]-value[i][1]-value[i][2]>=0)f[i][j] = max(f[i][j],f[i-1][j-value[i][0]-value[i][1]-value[i][2]] + value[i][0]*imp[i][0] + value[i][1]*imp[i][1] + value[i][2]*imp[i][2]);}elsef[i][j] = f[i-1][j];}}printf("%d\n",f[m][n]);return 0;
} 

P.S:一开始有个assembler messages的错误,纠结的半天,原来是一开始弄的f[maxn][maxn]数组太大爆炸了,

算法提高 金明的预算方案相关推荐

  1. (01背包扩展) 算法提高 金明的预算方案

      算法提高 金明的预算方案   时间限制:1.0s   内存限制:256.0MB     

  2. Java实现 蓝桥杯算法提高金明的预算方案

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

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

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

  4. 信息学奥赛一本通 1844:【06NOIP提高组】金明的预算方案 | 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案

    [题目链接] ybt 1844:[06NOIP提高组]金明的预算方案 洛谷 P1064 [NOIP2006 提高组] 金明的预算方案 [题目考点] 1. 动态规划:分组背包 2. 动态规划:依赖背包 ...

  5. 【背包DP练习】洛谷 P5020货币系统 P1757通天之分组背包 P1064[NOIP2006 提高组]金明的预算方案 P5322 [BJOI2019]排兵布阵

    洛谷 P5020货币系统 https://www.luogu.com.cn/problem/P5020 思路是把货币从小到大排序,然后按顺序依次完全背包dp,每次dp检查i-1种面值的货币能不能凑出第 ...

  6. P1064 金明的预算方案

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

  7. 金明的预算方案(分组背包)

    T2 金明的预算方案 http://www.tyvj.cn/p/1057 背景 NOIP2006 提高组 第二道 描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房 ...

  8. 依赖背包dp NOIP2006 vijos 1313 金明的预算方案

    依赖背包: 简化的问题 这种背包问题的物品间存在某种"依赖"的关系.也就是说,物品i依赖于物品j,表示若选物品i,则必须选物品j.为了简化起见,我们先设没有某个物品既依赖于别的物品 ...

  9. bsoj 1512 金明的预算方案(树型DP)

    [NOIP 2006提高]金明的预算方案   Time Limit:10000MS  Memory Limit:65536K Total Submit:485 Accepted:222  Case T ...

最新文章

  1. ORACLE RAC 11.2.0.4 for RHEL6.8 集群CRS异常导致集群命令无法使用
  2. Python将被加入高考科目?你怎么看?
  3. 一直在构建工作空间_基于用户场景构建的建筑工程弱电设计工作设想
  4. 在JSP中读取POST的JSON数据
  5. Kotlin实战指南十五:协程泄漏
  6. 数据库性能(一):数据库索引原理解析
  7. Audit(查看审核/审计信息)
  8. 使用缓存的9大误区(上)(转)
  9. hdu2069(Coin Change)
  10. centos7安装java6_CentOS7.6安装openjdk
  11. XFS:大数据环境下Linux文件系统的未来?
  12. 【python使用】使用python读取mid/mif文件,高精地图解析
  13. Ubuntu 中使用 xdg-open 命令高效打开文件
  14. 英特尔CAS缓存加速软件优化SSD性能
  15. Tableau-仪表板
  16. 流动性风险与次贷危机
  17. 如何使用Google Scholar(谷歌学术)
  18. 第8章 第七天 - 电影网站整合/集成到公众号
  19. 2019技术大赛预选赛 writeup
  20. ST120G坏道恢复案例

热门文章

  1. LNMP 配置漏洞系列解读
  2. 2020年“有史以来”全网最全1309道BAT大厂java面试题,mongodb原理知识
  3. Java:判断是一年的第几天
  4. android 3dtouch插件,标注点支持3DTouch效果
  5. 美女直播这么火,那你知道怎么测试直播软件吗?
  6. HTTP协议分析实验
  7. VBA:完美解决数独问题----全网最强
  8. 全网通拓扑图之聚合链路
  9. 钉钉申请发起后台提现接口
  10. 层次softmax (hierarchical softmax)理解