Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 24860 Accepted Submission(s): 10062
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#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> //第一次提交WA //后来看了discuss,原来是还可以骨头没重量但是有价值的,但是还是WA,这其实真的是一道很基本的DP0-1背包问题 //这个就是最基本的0-1背包问题,拿或不拿 #define MAXX 1005 int map[MAXX]; int value[MAXX]; int ans[MAXX]; int visit[MAXX]; //这个是否拿了,表示第几个物体已经被拿了 int N = 0; int V = 0; int maxindex = 0; void init() { int i = 0; for (i = 0; i <= MAXX; i++) //i要从0开始啊,怎么能从1开始啊,竟然还犯这样的错误啊,不应该啊 { map[i] = 0; value[i] = 0; ans[i] = 0; visit[i] = 0; } N = 0; V = 0; maxindex = 0; return; } int max(int a, int b) { if (a < b) { //printf("4--a = %d,b = %d,maxindex = %d\n", a, b, maxindex); return b; } else { return a; } } //一维数组AC void dp() { int i = 0; int j = 0; //自己写的犯了2个问题,1:应该是用物体个数做主循环,2:而且如果是用一维数组,V应该是从v-0这个顺序开始 //dp没什么visit这样的标志 #if 0 for (i = 0; i <= V;i++) //背包的重量,自己是从2开始的,但是我前面0,1都有涉及的 { maxindex = 0; //ans[i] = ans[i-1]; //这个很关键,自己一直没写对,这个很关键,这个值的初始值应该是前一个值,然后做比较 for (j = 1; j <= N;j++) { if (visit[j]) continue; //printf("1--%d - %d = %d\n", i, map[j], i - map[j]); if ((i-map[j]) >=0) { //printf("2--tmpans[%d] = %d,after= %d, value[%d] = %d\n", i, ans[i], ans[i - map[j]] + value[j], j, value[j]); ans[i] = max((ans[i - map[j]] + value[j]), ans[i],j); //反复循环新的值和ans[i]比较,直到找到ans[i]的最大值 //别人的背包都不用加visit这些东西来标记的。。。自己的思想其实是应该用二维数组来表示的,不是所有的都要用1维表示的 } } //printf("3--ans[%d] = %d,maxindex = %d\n", i, ans[i], maxindex); visit[maxindex] = 1; } #endif for (i = 1; i <= N;i++) { for (j = V; j >= 0;j--) //逆序 当内循环是逆序时,就可以保证后一个f[v]和f[v-c[i]]+w[i]是前一状态的! { if ((j - map[i])<0) continue; //这个不能忘 ans[j] = max((ans[j - map[i]] + value[i]), ans[j]); } } return; } int main() { int i = 0; int j = 0; int T = 0; int sum = 0; freopen("input.txt","r",stdin); scanf("%d",&T); for (i = 1; i <= T;i++) { //printf("111:%d\n", ans[0]); init(); //printf("222:%d\n", ans[0]); //sum = 0; scanf("%d %d", &N, &V); //printf("333:%d\n", ans[0]); for (j = 1; j <= N;j++) { scanf("%d", &value[j]); } for (j = 1; j <= N; j++) { scanf("%d", &map[j]); #if 0 if (0 == map[j]) { sum += value[j]; } if (1 == map[j]) { ans[1] = value[j]; //V=1的时候最大值肯定就是体积是1的价值 visit[j] = 1; } #endif } #if 0 if (0 == V) { printf("%d\n", sum); continue; } if (1 == V) { printf("%d\n", sum + ans[1]); continue; } #endif dp(); //还有一种方法是用二维数组的dp[i][v]=max{dp[i-1][v],dp[i-1][v-cost[i]]+value[i]} printf("%d\n",ans[V]); } return 0; }