博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1064 金明的预算方案
阅读量:6941 次
发布时间:2019-06-27

本文共 2923 字,大约阅读时间需要 9 分钟。

P1064 金明的预算方案

题目描述

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

主件 附件

电脑 打印机,扫描仪

书柜 图书

书桌 台灯,文具

工作椅 无

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是10元的整数倍)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为j1,j2,……,jk,则所求的总和为:

v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*为乘号)

请你帮助金明设计一个满足要求的购物单。

输入输出格式

输入格式:

 

输入的第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是所属主件的编号)

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
1000 5800 2 0400 5 1300 5 1400 3 0500 2 0
输出样例#1:
2200

说明

NOIP 2006 提高组 第二题

 

分析:

这是一个有依赖的背包问题,可以用分组背包的方法来做。

把所有有依赖的东西全部分在一组里面。然后我们以组为单位进行背包。

f[i][j]表示前i组物品中消耗为j的最大收益。

如果我们选第i组物品:

f[i][j]= f[i-1][j-v[i]]+w[i];

如果我们不选第i组物品:

f[i][j]= f[i-1][j];

 

然而,在这里,每组物品都包含多种情况:

只选主件;选主件和附件一;选组件和附件二………….

依次枚举就好。

如果情况很多,可以用循环。情况表示方法的话可以考虑用位来表示。

 

其实,所有的背包问题都能用分组背包的思想来做:

比如01背包:每件物品看成一组,每组只有一件物品

比如完全背包:每件物品看成一组,每组最多W/w[i]件物品

比如多重背包:每件物品看成一组,每组最多n[i]件物品

……..

 

1 #include 
2 #include
3 using namespace std; 4 int f[32010],v[70],q[70],p[70],v1[70],q1[70],v2[70],q2[70]; 5 int mymax(int x,int y) 6 { 7 return x>y?x:y; 8 } 9 int main()10 {11 int n,m;12 scanf("%d%d",&n,&m);13 /*q,v:如是主件则存在这里14 q1,v1:如是附件一存在这里15 q2,v2:如是附件二则存在这里*/16 memset(f,-1,sizeof(f));17 memset(q,0,sizeof(q));18 memset(q1,0,sizeof(q1));19 memset(q2,0,sizeof(q2));20 memset(v,0,sizeof(v));21 memset(v1,0,sizeof(v1));22 memset(v2,0,sizeof(v2));23 //请自动忽略以上的的OVO24 25 f[0]=0;26 for (int i=1;i<=m;i++)27 {28 int a,b,c;29 scanf("%d%d%d",&a,&b,&c);30 if (c==0)31 {32 v[i]=a;q[i]=b; //存为主件 33 } 34 else 35 {36 if (q1[c]==0) {q1[c]=b;v1[c]=a;}37 else {q2[c]=b;v2[c]=a;}38 //存为附件一或附件二39 }40 } 41 for (int i=1;i<=m;i++)42 {43 for (int j=n;j>=v[i];j--)44 {45 //if(f[j]!=-1)46 {47 if (j-v[i]>=0) f[j]=mymax(f[j],f[j-v[i]]+v[i]*q[i]);//只买一个主件48 if (j-v[i]-v1[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v1[i]]+v[i]*q[i]+v1[i]*q1[i]);//买主件和附件一49 if (j-v[i]-v2[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v2[i]]+v[i]*q[i]+v2[i]*q2[i]);//买主件和附件二50 if (j-v[i]-v1[i]-v2[i]>=0) f[j]=mymax(f[j],f[j-v[i]-v1[i]-v2[i]]+v[i]*q[i]+v1[i]*q1[i]+v2[i]*q2[i]);//买主件和两个附件51 }52 }53 }54 int ans=0;55 for (int j=1;j<=n;j++)56 {57 if (f[j]>ans) ans=f[j];58 //不一定用最多钱的就是最优的,扫一遍最大值59 }60 printf("%d\n",ans);61 return 0;62 }

 

转载地址:http://lvfnl.baihongyu.com/

你可能感兴趣的文章
C语言的数组初始化
查看>>
rtesseract的例子
查看>>
[Papers]NSE, $\p_3u$, Lebesgue space [Penel-Pokorny, AM, 2004]
查看>>
同样的so,放到不同的project中,就会报错
查看>>
mysql 锁
查看>>
android动画-动画分类及代码演示样例
查看>>
Java中的锁(转)
查看>>
Codeforces Round #288 (Div. 2) E. Arthur and Brackets 贪心
查看>>
用cocos2d-x 3.2 实现的FlappyBird
查看>>
http://jadethao.iteye.com/blog/1926525
查看>>
菜鸟要做架构师(三)——单元测试的七种境界
查看>>
Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)
查看>>
类在编写过程中的一些注意事项
查看>>
怎样解决栈溢出
查看>>
iTextSharp带中文转换出来的PDF文档显示乱码
查看>>
分享改进 完全定制自己的代码生成器
查看>>
object-c 获得目录(包括子目录)下所有文件和文件夹路径
查看>>
nginx自定义模块编写-实时统计模块--转载
查看>>
【leetcode】 search Insert Position(middle)
查看>>
我爱免费之FreeFileSync文件夹同步软件
查看>>