华为OJ---购物单

来源:互联网 发布:药品网络销售总总结 编辑:程序博客网 时间:2024/06/05 04:46

问题描述:

王强今天很开心,公司发给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<iostream>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<<f[N];delete []f;   //释放动态数组内存,养成良好的编程习惯 return 0;}


原创粉丝点击