Bone Collector

 

Bone Collector

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 11   Accepted Submission(s) : 10
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 ? [center][img]../../../data/images/C154-1003-1.jpg[/img] [/center]
 

 

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[sup]31[/sup]).
 

 

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

 

Sample Output
14
 

 

Author
Teddy
 

 

Source
HDU 1st “Vegetable-Birds Cup” Programming Open Contest
题目大意:
    和01背包差不多,第一行输入T组测试样例,每一组测试样例有三行,第一行时输入两个数据N和V,N表示有多少个的骨头。V表示背包的最大容量。当然,每一个骨头都有自己的价值和重量。下一行就是让你输入每一个骨头对应的价值,接下去一行就是让你输入对应骨头的重量。然后,询问你有V的容量大小的背包,最多可以装多少价值的骨头。(每一个骨头都是唯一的,仅能装一次,背包可以不用装满)。
状态:
    用SIGN[j]来保存每一次向背包大小为j的背包装入骨头,所能装入的最大价值。
    PACK[i]用来保存出入骨头的价值和重量。
状态转移方程:
    SIGN[j]=MAX{SIGN[j-PACK[i].Volume]+PACK[i].Value,SIGN[j]};/*装入第i个骨头的时候,判断是否需要更新相关背包容量的最大价值*/
空间复杂度:O(V), 时间复杂度O(N*V);
 1 #include<stdio.h>
 2 #include<string.h>
 3 typedef struct
 4 {
 5     int Value ;
 6     int Volume ;
 7 }XY;
 8 XY PACK[1010];/*保存物品的价值和重量*/
 9 int SIGN[1010];/*依次保存每一个背包大小所能存放的最大价值*/
10 
11 int main()
12 {
13     int T,N,V,i,j;
14     scanf("%d",&T);
15     while(T--)
16     {
17         scanf("%d%d",&N,&V);
18         memset(SIGN,0,sizeof(SIGN));/*因为背包可以不用装满,所以初始化为0*/
19         for(i=0;i<N;i++)
20             scanf("%d",&PACK[i].Value);     /*输入每一个骨头的价值*/
21         for(i=0;i<N;i++)
22             scanf("%d",&PACK[i].Volume);    /*输入每一个骨头的重量*/
23         for(i=0;i<N;i++)                    /*当装入第(i+1)个骨头的时候,更新SIGN[]上的最大价值*/
24             for(j=V;j>=PACK[i].Volume;j--)      /*因为每一个骨头都是唯一存在的,仅能装一次,所以需要从后面开始*/
25             {                                   /*才不会出现有重复累加同一个骨头的部分,从后开始可以保证每一次*/ 
26                 if(SIGN[j]<(SIGN[j-PACK[i].Volume]+PACK[i].Value))  /*装入的骨头都是与之前装入的骨头没有关系*/
27                     SIGN[j]=SIGN[j-PACK[i].Volume]+PACK[i].Value;  /*否则会出现,唯一能装入一次的骨头多次被装入*/
28                 if(i==N-1)break;                        /*在添加最后一个数据后,比较更新,即可*/
29             }
30         printf("%d\n",SIGN[V]);        /*既为输出背包容量为V,所能存的骨头的最大价值,也为题目所求的*/
31     }
32     return 0;
33 }
View Code

用DP[i][j]记录的做法:

#include <iostream>
#include <string.h>
#include <stdio.h>
#define Max(a,b)(a>b?a:b)
using namespace std;
int DP[1010][1010]={0};/*DP[i][j]表示放第i个物品,j表示当前背包的容量,放第i个物品,容量为j的最大价值*/
/*DP[i][j]取决于放第i-1个物品容量为j-W[i]的价值+V[i]的价值和放第i-1个物品容量为j的时候的最大值*/
/*DP[i][j]=max(DP[i-1][i-W[i]]+V[i],DP[i-1][j]);当j>=W[i]时*/
/*DP[i][j]=DP[i-1][j];当j<W[i]时*/
int main()         
{
    int T,n,m,i,j;
    int W[1010];
    int V[1010];
    int Num[1010];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&n,&m);
        for(j=1;j<=n;j++)scanf("%d",&V[j]);/*第i个物品的权值*/
        for(i=1;i<=n;i++)scanf("%d",&W[i]);/*第i个物品的重量*/
       // memset(DP,0,sizeof(DP));/*初始化DP*/
        for(i=1;i<=n;i++)/*n个物品*/
        {
            for(j=0;j<=m;j++)/*遍历所有能够装下的背包容量*/
            {
                if(j>=W[i])
                    DP[i][j]=Max(DP[i-1][j-W[i]]+V[i],DP[i-1][j]);
                else 
                    DP[i][j]=DP[i-1][j];
                //printf("%d ",DP[i][j]);
            }
           // putchar(10);
        }
        printf("%d\n",DP[n][m]);/*放第n个物品,背包容量为m的价值的最大值*/
    }
    return 0;
    
}
View Code

 

posted @ 2014-08-06 13:17  Wurq  阅读(195)  评论(0)    收藏  举报