HDU2602 (0-1背包)

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 39259    Accepted Submission(s):
16261

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

题意:给出n件物品的重量和价值,放进一个容量为v的背包,使背包里的价值最大。

0-1背包的模板题,可以有两种解法。

一维数组:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int  w[1100],p[1110];
int f[1110];
int main()
{
    int t,n,v;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&v);
        for(int i=1;i<=n;i++)
        scanf("%d",&w[i]); //输入物品重量
        for(int i=1;i<=n;i++)
        scanf("%d",&p[i]); //输入物品价值
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)
        {
            for(int j=v;j>=w[i];j--) //这个循环保证了放进去的物品重量不会超过背包所能容纳的重量
            {
                if(f[j] < f[j-w[i]] + p[i])  // 如果当前所拥有价值  小于 加上这件物品时创造的价值就更新
                f[j]= f[j-w[i]] + p[i];
                //   f[j] 表示背包重量为 j 时背包里的最大价值,
                //  所以f[ j - w[i] ] 表示放进这件物品时的状态(因为放进该件物品后容量就减少了)
            }
        }
        printf("%d\n",f[v]);
    }
    return 0;
}

二维数组:

 1  #include<stdio.h>
 2  #include<string.h>
 3  #include<algorithm>
 4  using namespace std;
 5  int w[1100],p[1110];
 6  int f[1110][1110];
 7  int main()
 8  {
 9      int t,n,v;
10      scanf("%d",&t);
11      while(t--)
12      {
13          scanf("%d%d",&n,&v);
14          for(int i=1;i<=n;i++)
15          scanf("%d",&p[i]);
16          for(int i=1;i<=n;i++)
17          scanf("%d",&w[i]);
18          memset(f,0,sizeof(f));
19          for(int i=1;i<=n;i++)
20          {
21              for(int j=0;j<=v;j++)
22              {
23                  if(w[i]<=j) // 这件物品的重量小于当前的容量,也就是说放的进背包
24                  {
25                      // f[i][j] 表示第 i 件物品在背包容量为 j 时的状态,
26                      //所以 f[i-1][j] 表示背包在上一次容量为 j 时候的状态,也就是没放这件物品的时候
27                      f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+p[i]);// 比较 没放进去之前 和放进该物品后 的价值,取最大
28
29                  }
30                  else f[i][j]=f[i-1][j];  // 如果不能放进该物品,则取上一次的状态
31              }
32          }
33          printf("%d\n",f[n][v]);
34      }
35      return 0;
36  }

渣渣一枚,如果有什么不对的地方,还请各位大神批评指正~  (^_^)

时间: 2024-10-30 14:10:56

HDU2602 (0-1背包)的相关文章

poj1417 带权并查集+0/1背包

题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是魔. 对于这些问题,我们只需要发现,如果回答对方是魔,那么即可以判断出这两个不是同一种族,而如果回答对方是神,那么说明这两个是同一种族,那么就可以用带权并查集合并这些神和魔,然后记录两种分别多少个,这样当所有询问都处理完时我们就可以得到一系列的集合,每个集合分别有它的两个种族的人数,但是此时对于每个

NOJ 1860 保研(0/1背包概率dp)

保研 时间限制(普通/Java):1000MS/3000MS         运行内存限制:65536KByte 总提交:171          测试通过:40 题目描述 对于一些名校而言,保研不仅可以由学校推免,也可以由学生自己向希望保研的学校提出申请,这个过程有点类似于外国学生向学校提交简历等待Offer的过程.但是,投递申请需要亲自去相应学校的研招办递交材料,这就需要一些成本(比如路费等),且每个院校都有自己的录取成功率.现在,请在总成本不超过限制的情况下,求出最大的成功率. 输入 输入

POJ 1636 Prison rearrangement DFS+0/1背包

题目链接: POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2194   Accepted: 984 Description In order to lower the risk of riots and escape attempts, the boards of two nearby prisons of equal

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,

牛客网 TaoTao要吃鸡 ( 0/1背包变形 )

题意 : 题目链接 分析 :  如果没有 BUG (即 h == 0 的时候)就是一个普通的 0 / 1 背包 需要讨论一下 h != 0 的情况 此时有就相当于有物品是有特权的 而且背包装有特权的物品根据题目的要求是应当最后装的 也就是说特权物品装完之后背包将不再可装 所以特权物品肯定是只有一个的 数据量并不大,所以可以去枚举这个特权物品 那么如何知道在  没有装特权物品  之前的最佳选择方案? 答案就是用最小的可剩空间留给特权物品,然后其他空间去跑 0/1 背包 最小的可剩空间当然就是 h

浙大PAT CCCC L3-001 凑零钱 ( 0/1背包 &amp;&amp; 路径记录 )

题目链接 分析 : 就是一个 0/1 背包,但是需要记录具体状态的转移情况 这个可以想象成一个状态转移图,然后实际就是记录路径 将状态看成点然后转移看成边,最后输出字典序最小的路径 这里有一个很巧妙的做法 先将所有的硬币升序排序(这一点很重要) 然后在这一条件下,假设当前状态是考虑第 i 个硬币,前一个状态是考虑第 i-1 个硬币 试想对于同一个体积,如果选用的硬币数量越多是不是字典序更小 然后对于如果对于同一体积下,选用硬币数一样多的两种方案 由于我们已经升序排序,如果有一样多硬币的情况,那么

POJ 1745 【0/1 背包】

题目链接:http://poj.org/problem?id=1745 Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13431   Accepted: 4774 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequen

hdu 2191 悼念512同胞(0 1背包)

Input 输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格.每袋的重量以及对应种类大米的袋数. Output 对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完.每

0 1背包模板

# include <stdio.h> # include <stdlib.h> # include <string.h> # define max(x,y) x>y?x:y; int v[1001];//价值 int w[1001];//重量 int dp[1001][1001]; int main() { int n,m; while(scanf("%d%d",&m,&n)!=EOF) { memset(dp,0,sizeo

动态规划—0/1背包

问题描述:每种物品仅有一件,wi代表物体i的重量,pi表示物体i的价值,物体不可拆分,可以选择放或不放.背包总容量M,求怎么放才能价值最大化? 分析: java代码: 1 public class Package01 { 2 3 //3个物体的重量 4 public static int[] m = {3,4,5}; 5 6 //物体的价值 7 public static int[] p = {4,5,6}; 8 9 //背包的总容量 10 public static int M = 10; 1