03_01背包问题

来源:刘汝佳《算法竞赛入门经典--训练指南》 P60 问题4:

问题描述:有n种物品,每种只有一个,第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包中,使得背包内物品在总体积不超过C的前提下重量尽量大。其中,1<=n<=100。1<=V<=C<=10000。1<=Wi<=10^6。

分析:用f[i][j]表示“把前i个物品装到容量为j的背包中的最大总重量”,则状态转移方程为f[i][j] = Max{f[i-1][j],f[i-1][j-Vi]+Wi | Vi<=j};

滚动数组优化后代码:

 1 memset(f,0,sizeof(f));
 2 for(int i=1; i<=n; i++)
 3 {
 4     scanf("%d %d",&V,&W);
 5     for(int j=C; j>=0; j--)
 6     {
 7         if(j>=V) 
 8             f[j] = Max(f[j],f[j-V]+W);
 9     }
10 }

例题来源:http://acm.hdu.edu.cn/showproblem.php?pid=2602

例题:hdu 2602

Bone Collector

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

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( V <= 1000)的背包和n(n <= 1000 )个骨头,每个骨头i有各自的体积volume[i]和价格value[i],求在不超过背包体积V的前提下往背包里装骨头的最大价值。

代码实现:

 1 #include "stdio.h"
 2 #include "string.h"
 3 #define N 1005
 4 int dp[N];
 5 int value[N];  //价值数组
 6 int volume[N]; //体积数组
 7 
 8 int Max(int a,int b) { return a>b?a:b; }
 9 
10 int main()
11 {
12     int T;
13     int n,V;  //n为骨头数量,V为背包体积
14     int i,j,v,w;
15     scanf("%d",&T);
16     while(T--)
17     {
18         scanf("%d %d",&n,&V);
19         memset(dp,0,sizeof(dp));
20         for(i=0; i<n; i++)
21             scanf("%d",&value[i]);
22         for(i=0; i<n; i++)
23             scanf("%d",&volume[i]);
24         for(i=0; i<n; i++)
25         {
26             v = volume[i]; //第i个骨头的体积
27             w = value[i]; //第i个骨头的价值
28             for(j=V; j>=v; j--)
29                 dp[j] = Max(dp[j],dp[j-v]+w);
30         }
31         printf("%d
",dp[V]);
32     }
33     return 0;
34 }
原文地址:https://www.cnblogs.com/ruo-yu/p/4384357.html