0-1背包问题

今天终于把0-1背包搞懂了,随笔记下。

关于0-1背包问题的算法,资料上写得再详细不过了。

阐述下问题:

有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下重量尽可能大。1≤n≤100,1≤Vi≤C≤10000,1≤Wi≤10^6。

推导出状态转移方程:

f[i][j] = max(f[i-1][j], f[i-1][j-Vi]+Wi)

f[i][j] 表示在放好第 i 个物品,总占用背包体积大小为 j 时,可装下最大质量 f[i][j]。

如果对于 f[i][j] 和  f[i-1][j-Vi] 的关系不是很清楚,那可以想成 f[i][k+Vi] 和  f[i-1][k] ,k表示放好第i-1个物品后总占用背包体积大小为k (k = j - Vi)。

以下是一组测试数据,及操作的过程。

修正:i = 4 的时候,j = 3,4,5 分别对应12,16,22

题目:POJ3624

用滚动数组写的代码

View Code
 1 #include <iostream>
2 #include <cstdio>
3
4 using namespace std;
5
6 const int MAXN = 12880;
7
8 template <class T>
9 T Max(T a, T b)
10 {
11 return (a > b)?a:b;
12 }
13
14 int main()
15 {
16 int N, M, V, W;
17 int f[MAXN+10];
18 memset(f, 0, sizeof(f));
19 scanf("%d%d", &N, &M);
20 for (int i = 1; i <= N; i++)
21 {
22 scanf("%d%d", &V, &W);
23 for (int j = M; j >= 0; j--)
24 {
25 if (j >= V)
26 {
27 f[j] = Max(f[j], f[j-V] + W);
28 }
29 }
30 }
31 printf("%d\n", f[M]);
32
33 return 0;
34 }

 

posted @ 2011-06-06 00:12  SubmarineX  阅读(457)  评论(0编辑  收藏  举报