HDU - 2602 Bone Collector(01背包讲解)

题意:01背包:有N件物品和一个容量为V的背包。每种物品均只有一件。第i件物品的费用是volume[i],价值是value[i],求解将哪些物品装入背包可使价值总和最大。

分析:

1、构造二维数组:dp[i][j]---前i件物品放入一个容量为j的背包可以获得的最大价值。

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - volume[i]] + value[i]);---(a)

(1)dp[i - 1][j]---不放第i件物品,因此前i件物品放入一个容量为j的背包的价值与前i-1件物品放入一个容量为j的背包的价值相同。

(2)dp[i - 1][j - volume[i]] + value[i]---放入第i件物品,因为当前背包容量为j,所以需要将前i-1件物品放入容量为j-volume[i]的背包里,剩下的容量为volume[i]的空间放第i件物品。

2、构造一维数组:dp[j]---当前状态是容量为j的背包所得价值。

dp[j] = max(dp[j], dp[j - volume[i]] + value[i]);---(b)

比较上述a式,

b式中的第一个dp[j]是考虑第i件物品的,即当前状态。

而 dp[j - volume[i]] + value[i]和第二个dp[j]是考虑第i-1件物品的,即前一个状态。

因此通过逆序枚举(V……volume[i])的方式更新dp[j]。

原因:因为如果正序,对于正在考虑的物品i,前面已更新的dp[j]会对后面更大容量的dp[j]的更新产生影响,

而逆序枚举,对于当前研究的物品i状态下的dp[j](即将计算),dp[j]和更小容量的dp[j - volume[i]]都是未更新的,也就是我们需要的前一状态,即第i-1件物品的情况。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-8;
inline int dcmp(double a, double b){
    if(fabs(a - b) < eps) return 0;
    return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 1000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int value[MAXN], volume[MAXN], dp[MAXN];
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        int N, V;
        scanf("%d%d", &N, &V);
        for(int i = 0; i < N; ++i){
            scanf("%d", &value[i]);
        }
        for(int i = 0; i < N; ++i){
            scanf("%d", &volume[i]);
        }
        memset(dp, 0, sizeof dp);
        for(int i = 0; i < N; ++i){
            for(int j = V; j >= volume[i]; --j){
                dp[j] = max(dp[j], dp[j - volume[i]] + value[i]);
            }
        }
        printf("%d\n", dp[V]);
    }
    return 0;
}

  

时间: 2024-12-04 10:35:45

HDU - 2602 Bone Collector(01背包讲解)的相关文章

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>

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

HDU 2602 Bone Collector (01背包问题)

原题代号:HDU 2602 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 原题描述: 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 ,

HDU 2602 (简单的01背包) Bone Collector

很标准的01背包问题 1 //#define LOCAL 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 1000 + 10; 8 int w[maxn], v[maxn], dp[maxn]; 9 10 int main(void) 11 { 12 #ifdef LOCAL 13 freopen(&qu

hdu 2602 Bone Collector 【01背包模板】

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

HDU 2602 Bone Collector 0/1背包

题目链接:pid=2602">HDU 2602 Bone Collector Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 28903    Accepted Submission(s): 11789 Problem Description Many years ago , in Teddy's h

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背包)模板

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 54132    Accepted Submission(s): 22670 Problem Description Many years ago , in