HDOJ Bone Collector

 

Bone Collector

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 6   Accepted Submission(s) : 2
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

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
 
//参考 http://baike.baidu.com/view/841810.htm
//递归实现
//A[i][v]表示剩余空间为v时选取当前物品i的最大值
//B[i][v]表示剩余空间为v时不选取当前物品i的最大值
//所以总的最大值就是 max{A[n][v],B[n][v]}.
#include<iostream>
using namespace std;
const int maxsize=1001;
int A[maxsize][maxsize],B[maxsize][maxsize];
int volume[maxsize],value[maxsize];
int F(int n,int v){
    if(n==0)  return 0;
    if(!A[n][v] && v>=volume[n] ) //如果在剩余体积为V时第n个物品没有加入过,且剩余体积大于该物品的体积
         A[n][v]=F(n-1,v-volume[n]) + value[n]; //把第n个物品加入,查询其他的n-1个物品
    if(!B[n][v]) //如果不加入第n个物品
         B[n][v]=F(n-1,v);
    return A[n][v]>B[n][v]?A[n][v]:B[n][v];
}
int main(){
    int t,n,v;
    scanf("%d",&t);
    while(t--){
         memset(A,0,sizeof(A));
         memset(B,0,sizeof(B));
         scanf("%d%d",&n,&v);
         for(int i=1;i<=n;i++)
              scanf("%d",&value[i]);        
         for(int i=1;i<=n;i++)
              scanf("%d",&volume[i]);
         printf("%d\n",F(n,v));
    }
    //system("pause");
    return 0;
}
上面的递归太费时间和空间了,建议用下面的做法。
#include<iostream>
using namespace std;
int value[1001],volume[1001],bag[1001]; //bag存放所能取的最大价值
int main(){
    int T,N,V;
    scanf("%d",&T);
    while(T--){
         memset(bag,0,sizeof(bag));
         scanf("%d%d",&N,&V);
         for(int i=1;i<=N;i++)
               scanf("%d",&value[i]);
         for(int i=1;i<=N;i++)
               scanf("%d",&volume[i]);
         for(int i=1;i<=N;i++)
              for(int v=V;v>=volume[i];v--)
                    bag[v]=max(bag[v],bag[v-volume[i]]+value[i]);
         printf("%d\n",bag[V]);          
    }  
    //system("pause");
    return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值