您的位置:首页 > 其它

金明的预算方案

2014-04-24 11:31 162 查看
Problem Description

金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只有不超过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]

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

Input

输入有多组数据,每组数据第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是所属主件的编号)

Output

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

Sample Input

1000 5

800 2 0

400 5 1

300 5 1

400 3 0

500 2 0

Sample Output

2200

#include<stdio.h>
#include<string.h>
int dp[320010],price[65][3],value[65][3];
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
//freopen("b.txt","r",stdin);
int n,m,pc,ip,at,i,j,k;
while(scanf("%d %d",&n,&m)==2)
{
memset(dp,0,sizeof(dp));
memset(price,0,sizeof(price));
memset(value,0,sizeof(value));
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&pc,&ip,&at);
if(at==0)
{
price[i][0]=pc;
value[i][0]=pc*ip;
}
else
{
if(!price[at][1])
{
price[at][1]=pc;
value[at][1]=pc*ip;
}
else
{
price[at][2]=pc;
value[at][2]=pc*ip;
}
}
}
for(i=1;i<=m;i++)
{
for(j=n;j>=1;j--)
{
if(j>=price[i][0])
dp[j]=max(dp[j],dp[j-price[i][0]]+value[i][0]);
if(j>=price[i][0]+price[i][1])
dp[j]=max(dp[j],dp[j-price[i][0]-price[i][1]]+value[i][0]+value[i][1]);
if(j>=price[i][0]+price[i][2])
dp[j]=max(dp[j],dp[j-price[i][0]-price[i][2]]+value[i][0]+value[i][2]);
if(j>=price[i][0]+price[i][1]+price[i][2])
dp[j]=max(dp[j],dp[j-price[i][0]-price[i][1]-price[i][2]]+value[i][0]+value[i][1]+value[i][2]);
}
}
printf("%d\n",dp
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: