您的位置:首页 > 其它

HDU 2602 Bone Collector (简单的0-1背包)(AC)

2016-10-08 15:12 302 查看


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 ?



 

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

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;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: