我真的不黑博士
问题描述
博士正在搭建巴比伦巨塔! ! ! ! (具体情节参看银魂)
但是要和宙斯 PK! ! !
怎么办,本身就是一个高帅富的博士立刻就掏出了 N 元钱,跨上自己的加长火焰加强黄金豪华最终版特典限量劳斯莱斯和兰博基尼公司合作制造的跑车,飞到了纽约(跑车带007 特种功能,可以绕地球 20 圈,淘宝限量购买仅剩一件,售价 1000 万张末日船票) ,去找奥巴马和老小布什购买一些必须的物品。
他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件 | 附件 |
---|---|
链锯 | 合金刀片,高转速引擎 |
火焰枪 | 集火喷枪头 |
城管标配 | 城管式拉风袖章 |
加特林机关枪 | 无 |
如果要买归类为附件的物品,必须先买该附件所属的主件。
每个主件可以有
附件不再有从属于自己的附件。
博士想买的东西很多,为了防止有用的东西没买,他把每件物品规定了一个重要度,分为
5
等:用整数
他还从因特网上查到了每件物品的价格(都是
10
元的整数倍) 。
他希望在不超过
N
元(可以等于
设第
j
件物品的价格为
(其中*为乘号)
请你帮助博士设计一个满足要求的购物单,博士会赏你一堆巴比伦塔尖搞到的牛奶的。
输入
输入文件名为 TribleBlackBS.in。
输入第一行包含两个正整数
N
和
后接
M
行,每行
输出
输出文件名为 TribleBlackBS.out。
输出一行一个正整数,为最大的总和的值。
输入样例
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
数据范围
对于
100%
的数据,
2<=N<=32000
,
1<=M<=60
,
1<=Pi<=5
,
1<=Vi<=10000
,
答案在带符号 32 位整形变量的存储范围内。
Solution
同 NOIP2006 金明的预算方案,树形依赖背包问题。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max(x,y) ((x)>(y)?(x):(y))
using namespace std;
int n,m,cnt;
int w[100];
int c[100];
int f[100][40000];
int head[100],data[100],nxt[100];
void add(int x,int y){
nxt[cnt]=head[x];data[cnt]=y;head[x]=cnt++;
}
void dfs(int s,int v){
if(v<=0)return;
for(int i=head[s];i!=-1;i=nxt[i]){
int d=data[i];
for(int j=0;j<=v-c[d];j++)f[d][j]=f[s][j]+w[d];
dfs(d,v-c[d]);
for(int j=c[d];j<=v;j++)
f[s][j]=Max(f[s][j],f[d][j-c[d]]);
}
}
int main(){
freopen("tribleblackbs.in","r",stdin);
freopen("tribleblackbs.out","w",stdout);
memset(head,-1,sizeof head);
scanf("%d%d",&m,&n);
m/=10;
for(int i=1;i<=n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
c[i]=x/10;
w[i]=x*y;
add(z,i);
}
dfs(0,m);
printf("%d\n",f[0][m]);
return 0;
}