HDU 3449 Consumer

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3449

题意:

有n个箱子,总共有多少money,箱子的价格为pi元,箱子价值为0,每个箱子里装有mi个物品,每个物品价格cj元价值vj元,要买该箱子里的物品,必须得买了该箱子,求在那么多的money下,最多能买到多少价值的物品。

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

解析:背包问题,但是加了条件,必须得买了该箱子才能买箱子里的物品,作为新手的我,刚开始学背包问题,把我搞得够呛!

首先设置一个总的dp[]数组,再设置一个用来记录上一状态的中间数组temp[],

一层一层的做,也就是说求完一个箱子的最大价值后再求下一个箱子的最大价值,每一层对总的dp[]进行更新,到最后一层完成后,也就知道总的最大价值了,具体看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    int dp[100005],temp[100005];
    int box,money;
    while(scanf("%d %d",&box,&money)!=EOF)
    {
        memset(dp,0,sizeof(dp));//先对dp[]置0
        int pi,mi,cj,vj;
        for(int i=1;i<=box;i++)
        {
        scanf("%d %d",&pi,&mi);
        for(int i=0;i+pi<=money;i++)//用中间数组temp[]记录上一状态的最大价值,箱子价值为0,所以只需简单继承
            temp[i+pi]=dp[i];//这个转化关系式要理解透彻
        for(int i=1;i<=mi;i++)//对箱子里的每一个物品进行01背包的求最大价值
        {
            scanf("%d %d",&cj,&vj);
            for(int j=money;j>=pi+cj;j--)
            temp[j]=max(temp[j],temp[j-cj]+vj);//这里都是用中间数组temp[]在进行记录


        }
         for(int i=pi;i<=money;i++)//当一层算完后,也就是一个箱子算完后,用更新后中间记录数组temp[]与记录
            dp[i]=max(dp[i],temp[i]);//前一状态数组dp[]进行比较,更新dp[]数组,完成后进行下一个箱子的计算
        }
        printf("%d\n",dp[money]);//最后输出那么多money的最大价值
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值