华为OJ---购物单

问题描述:


王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

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

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为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 )。


样例输入:

1000 5 

800 2 0 

400 5 1 

300 5 1 

400 3 0 

500 2 0


样例输出:2200

//01背包问题 
#include
using namespace std;

int max(int x,int y)
{
	return(x>y?x:y);
} 

typedef struct{
	int value;    //物品价格 
	int priority; //物品的重压程度 
	int q;        //编号,0为主件,非0为附件 
}product;
product proVec[60];


int main()
{
	int N,m,i,j;
	cin>>N;   //总钱数 
	cin>>m;   //物品个数 
	for(i=1;i<=m;i++)
	   cin>>proVec[i].value>>proVec[i].priority>>proVec[i].q;
	
	int *f=new int[N+1];
	for(i=0;i<=N;i++)
	   f[i]=0;
	
	//完全背包问题
	for(i=1;i<=m;i++)
	{
		for(j=N;j>=10;j--)
		{
			if(j>=proVec[i].value)
			{
				if(proVec[i].q==0)
				{
					f[j]=max(f[j],f[j-proVec[i].value]+proVec[i].value*proVec[i].priority);
				}
				else
				{
					if(j>=proVec[i].value+proVec[proVec[i].q].value)
					{
						f[j]=max(f[j],f[j-proVec[i].value-proVec[proVec[i].q].value]+
						proVec[i].value*proVec[i].priority+proVec[proVec[i].q].value*proVec[proVec[i].q].priority);
					}
				}
			}
		}
	} 
	cout<


你可能感兴趣的:(C/C++学习,华为OJ)