Time Limit:10000MS Memory Limit:65536K Description 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子: Input 输入文件的第1行,为两个正整数,用一个空格隔开: Output 输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<200000)。 Sample Input
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
Sample Output
2200
Source xinyue —— Noip2006 第二题 |
题目:http://mail.bashu.cn:8080/bs_oj/showproblem?problem_id=1512
题意:金明要购买m件物品,而且钱数不能超过n,有的物品有依赖关系。。。
分析:类似选课那题,不过这题如果没有优化的话,估计是过不去了。。。
代码:
#include<cstdio> #include<iostream> using namespace std; const int mm=33333; int f[99][mm],v[99],p[99],q[99]; int i,n,m; void TreeDP(int k,int c) { if(c)for(int i=1,j;i<=n;++i) if(q[i]==k) { for(j=0;j<=c-v[i];++j)f[i][j]=f[k][j]+v[i]*p[i]; TreeDP(i,c-v[i]); for(j=v[i];j<=c;++j) f[k][j]=max(f[k][j],f[i][j-v[i]]); } } int main() { while(~scanf("%d%d",&m,&n)) { for(i=1;i<=n;++i) scanf("%d%d%d",&v[i],&p[i],&q[i]); for(i=0;i<=m;++i)f[0][i]=0; TreeDP(0,m); printf("%d\n",f[0][m]); } return 0; }