杭电ACM 2602 Bone Collector背包

来源:互联网 发布:cad怎么修改网络计划图 编辑:程序博客网 时间:2024/05/29 14:30

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 231).
 

Sample Input
15 101 2 3 4 55 4 3 2 1
 

Sample Output
14
 

Author
Teddy
 

Source
HDU 1st “Vegetable-Birds Cup” Programming Open Contest
 

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 1
原创粉丝点击