HDU 3449-Consumer

Consumer

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 2328    Accepted Submission(s): 1236


题目链接:点击打开链接


Problem Description
FJ is going to do some shopping, and before that, he needs some boxes to carry the different kinds of stuff he is going to buy. Each box is assigned to carry some specific kinds of stuff (that is to say, if he is going to buy one of these stuff, he has to buy the box beforehand). Each kind of stuff has its own value. Now FJ only has an amount of W dollars for shopping, he intends to get the highest value with the money.
 

Input
The first line will contain two integers, n (the number of boxes 1 <= n <= 50), w (the amount of money FJ has, 1 <= w <= 100000) Then n lines follow. Each line contains the following number pi (the price of the ith box 1<=pi<=1000), mi (1<=mi<=10 the number goods ith box can carry), and mi pairs of numbers, the price cj (1<=cj<=100), the value vj(1<=vj<=1000000)
 

Output
For each test case, output the maximum value FJ can get

Sample Input
3 800
300 2 30 50 25 80
600 1 50 130
400 3 40 70 30 40 35 60
 


Sample Output
210
 
题意:
FJ将会买一些东西,在此之前,他需要一些盒子来装他将要购买的不同种类的东西。每个盒子都被分配给一些特定的东西(也就是说,如果他要买这些东西,他必须事先买盒)。每种东西都有它自己的价值。现在,FJ的购物价值只有W美元,他打算用这笔钱来获得最高的价值东西。

第一行将包含两个整数,n ,代表盒子的数量(1< = n <= 50),w,代表FJ的钱,(1 <= w <= 100000),然后是n行。每一行包含以下数字pi,代表盒子的价格( 1<=pi<= 1000),mi ,代表第i个盒子可以携带 mi 个物品(1 <=mi<= 10),接下来mi对数字,价格cj(1 <=cj<= 100),值vj(1 <=vj<=1000000)


分析:
本题是有依赖性的背包题目,先对每组选择里的所有物品进行0-1背包处理,但背包容量为(总容量-盒子容量);然后跟上一组的状态比较来决定这一组选择 是选还是不选,取其中的较大值。


#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string>
#include<string.h>
using namespace std;

const int MAX=100005;
int dp[MAX];
int tmp[MAX];

int main()
{
    int n,sum,p,m,w,v;
    while(~scanf("%d%d",&n,&sum))
    {
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        {
            scanf("%d %d",&p,&m);
            memcpy(tmp,dp,sizeof(dp));///继承上一组的状态
            for(int j=0;j<m;j++)
            {
                scanf("%d%d",&w,&v);
                /**在上一组的状态下,对本组的每一个物品都进行01背包的筛选**/
                for(int k=sum-p;k>=w;k--)///记住容量是总容量减去当前盒子的容量
                    tmp[k]=max(tmp[k],tmp[k-w]+v);
            }
            for(int j=p;j<=sum;j++)///更新能更新的dp数组
                dp[j]=max(dp[j],tmp[j-p]); 
        }
        printf("%d\n",dp[sum]);
    }
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值