杭电ACM 2602 Bone Collector背包

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 58027    Accepted Submission(s): 24207


Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?

 

Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
 

Output
One integer per line representing the maximum of the total value (this number will be less than 2 31).
 

Sample Input
  
  
1 5 10 1 2 3 4 5 5 4 3 2 1
 

Sample Output
  
  
14
 

Author
Teddy
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1203  2159  2955  1171  2191 
 

做的第一道01背包题。
题意:骨头收集者!!骨头都有自己的value(价值)和volume(体积),现在给一个一定容积的袋子,问如何装才能装下最大价值的骨头。典型的01背包问题。以下列程序为例,若以二维数组d[1005][1005]来记录01背包表的值的话,动态方程为d[i][j]=max(d[I-1][j],d[I-1][j-b[I]]+a[I])以题目给定例子来画出下面的01背包表:


1

2

3

4

5

6

7

8

9

10

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

1

1

1

1

1

1

2

0

0

0

2

2

2

2

2

3

3

3

0

0

3

3

3

3

5

5

5

5

4

0

4

4

4

7

7

7

7

10

10

5

5

5

9

9

9

12

12

12

12

14

该表的第一行表示背包的大小j,第一列表示物品的价值a[I],这个表造成的疑问在于,列如为什么d[1][9]不是价值为1的物品加上价值为2的物品,他们的体积相加刚好是9啊!?这是因为在I=1这行,没有轮到价值大于1的物品来排。也就是说,第I行就是价值为1~I的物品去进行装填。按照这个道理,右下角最后一个格子里的就是我们要求的最大值。或许还是没懂,其实自己亲自把表里的值推推就会好些了。

原理懂了之后编程是水到渠成啊!


附上代码:
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int a[1005],b[1005];
int d[1005][1005];
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        memset(d,0,sizeof(d));
        int x,y;
        cin>>x>>y;
        for(int i=1;i<=x;i++)
            cin>>a[i];///价值
        for(int i=1;i<=x;i++)
            cin>>b[i];///所占空间
        for(int i=1;i<=x;i++)///动态规划
        {
            for(int j=0;j<=y;j++)
            {
                if(j>=b[i])
                    d[i][j]=d[i-1][j]>(d[i-1][j-b[i]]+a[i])?d[i-1][j]:(d[i-1][j-b[i]]+a[i]);
                else
                    d[i][j]=d[i-1][j];
            }

        }
        cout<<d[x][y]<<endl;
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值