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 ?
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.
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
//参考
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;
}
//递归实现
//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;
}
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;
}