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
用滚动数组写的代码
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 }
/**************************************************************************
                 
原文来自博客园——Submarinex的博客: www.cnblogs.com/submarinex/               
 
*************************************************************************/