【HDU2602】Bone Collector(01背包)

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 38586    Accepted Submission(s): 16007

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

给定容量V的背包 每一块骨头的体积和价值固定 之后求背包能装下的最大价值和

01背包问题就是 一次性使用骨头 方法常见的有二维数组和一维数组 一维数组是二维数组再空间上的优化 循环数组优化

先解释下二维数组的方法 状态转移方程是

dp[i][v] = max(dp[i-1][v], dp[i-1][v-c[i]]+w[i])

将前i件物品放入容量为v的背包中 是子问题 若只考虑第i件物品的策略(放或不放)那么就可以转化为一个只牵扯前i-1件物品的问题

实现代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1010;
int va[maxn], vo[maxn];
int dp[maxn][maxn];
int n, v;
int res;

int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &v);
        for(int i = 1; i <= n; ++i){
            scanf("%d", &va[i]);
        }
        for(int i = 1; i <= n; ++i){
            scanf("%d", &vo[i]);
        }
        memset(dp, 0, sizeof(dp));

        for(int i = 1; i <= n; ++i){
            for(int j = 0; j <= v; ++j){
                if(vo[i] <= j)
                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-vo[i]]+va[i]);
                else
                    dp[i][j]=dp[i-1][j];
            }
        }

        printf("%d\n", dp[n][v]);
    }
    return 0;
}

接下来我们说一下一维数组的方法 递推公式

for i <- 1 to N

do for v <- V to 0

do  dp[v] = max(dp[v], dp[v-c[i]]+w[i])

这里因为用到了滚动数组的感觉 所以第二重循环要逆序 这样才能保证每一次dp的更新是从上一层i-1更新得到

代码实现如下

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 1010;
int va[maxn], vo[maxn];
int dp[maxn];
int n, v;
int res;

int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        scanf("%d%d", &n, &v);
        for(int i = 0; i < n; ++i){
            scanf("%d", &va[i]);
        }
        for(int i = 0; i < n; ++i){
            scanf("%d", &vo[i]);
        }
        memset(dp, 0, sizeof(dp));

        for(int i = 0; i < n; ++i){
            for(int j = v; j >= vo[i]; --j){
                dp[j] = max(dp[j], dp[j-vo[i]] + va[i]);
            }
        }

        printf("%d\n", dp[v]);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-08 13:59:10

【HDU2602】Bone Collector(01背包)的相关文章

hdu2602 Bone Collector (01背包)

本文出自:http://blog.csdn.net/svitter 题意:典型到不能再典型的01背包.给了我一遍AC的快感. //============================================================================ // Name : 2602.cpp // Author : vit // Version : // Copyright : Your copyright notice // Description : Hello

HDU 2602 Bone Collector(01背包裸题)

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 60469    Accepted Submission(s): 25209 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bo

hdu 2602 Bone Collector 01背包

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 50442    Accepted Submission(s): 21153 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bon

HDU 2602 Bone Collector (01背包DP)

题意:给定一个体积,和一些物品的价值和体积,问你最大的价值. 析:最基础的01背包,dp[i] 表示体积 i 时最大价值. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream>

hdoj 2620 Bone Collector(0-1背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 思路分析:该问题为经典的0-1背包问题:假设状态dp[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值,则可以推导出dp递推公式 dp[i][v] = Max{dp[i-1][v], dp[i-1][v – c[i]] + w[i]}:c[i]表示第i件物品的容量,w[i]表示第i件物品的价值:该动态规划问题每个阶段的决策为是否要 选择第i件物品放入背包中,如果不选择第i件物

hdu 2602 Bone Collector 01背包模板

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 题目要求是尽量装的最多,所以初始化的时候都为0即可. 如果要求恰好装满,初始化的时候除了dp[0] = 0,其他都要设成-inf,表示不合法情况. 1 #include <bits/stdc++.h> 2 using namespace std; 3 int T; 4 int dp[1010][1010]; 5 int v[1010], w[1010]; 6 int main() 7 { 8

HDU2602 Bone Collector 【01背包】

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 28365    Accepted Submission(s): 11562 Problem Description Many years ago , in Teddy's hometown there was a man who was called "Bo

【模板--完全背包】HDU--2602 Bone Collector

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 volum

0-1背包问题(经典)HDU2602 Bone Collector

Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 36479    Accepted Submission(s): 15052 Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bon

Bone Collector 0-1背包问题

题目描述: 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 a