1. 问题描述
输入: n组输入<vi, wi>(vi, wi > 0)(value 价值, weight 重量), 最大重量 C;
输出: 一组代表选择的序列<x1, x2, …, xn>, 其中 xi ∈ {0, 1}, 即代表选择 / 不选择,使得下面两个条件成立:Σi=1nwixi≤C\Sigma_{i = 1}^{n} w_ix_i ≤ CΣi=1nwixi≤CmaxΣi=1nviximax\Sigma_{i = 1}^{n} v_ix_imaxΣi=1nvixi
(下面用这两个方程来代指某个0-1背包问题)
2.问题求解
2.1 最优解的结构
设<x1, x2, …, xn>是Σi=1nwixi≤C\Sigma_{i = 1}^{n} w_ix_i ≤ CΣi=1nwixi≤CmaxΣi=1nviximax\Sigma_{i = 1}^{n} v_ix_imaxΣi=1nvixi的一组最优解,则<x1, x2, …, xn-1>是Σi=1n−1wixi≤C−wnxn\Sigma_{i = 1}^{n - 1} w_ix_i ≤ C - w_nx_nΣi=1n−1wixi≤C−wnxnmaxΣi=1n−1viximax\Sigma_{i = 1}^{n - 1} v_ix_imaxΣi=1n−1vixi的一组最优解.注意到前后两组方程在最大重量和输入规模上有差异,因此有状态定义如下:
2.2 状态定义及状态转移方程
定义m[i][w]m[i][w]m[i][w]为限制输入规模在[1,i][1, i][1,i]且限制最大重量为www时的最大价值
m[1][w]=0 (0≤w<w1)m[1][w] = 0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0≤w<w_1)m[1][w]=0 (0≤w<w1)
m[1][w]=v1 (w≥w1)m[1][w] = v_1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(w≥ w_1)m[1][w]=v1 (w≥w1)
m[i][w]=m[i−1][w] (0≤w<wi)m[i][w] = m[i - 1][w]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0≤w<w_i)m[i][w]=m[i−1][w] (0≤w<wi)
m[i][w]=max(m[i−1][w],m[i−1][w−wi]+vi) (w≥wi)m[i][w] = max(m[i - 1][w], m[i - 1][w - w_i] + v_i)~~~~~~(w≥w_i)m[i][w]=max(m[i−1][w],m[i−1][w−wi]+vi) (w≥wi)
*前两个方程是递归的基础,后两个方程代表了这样一种递归逻辑: 当最大重量足够装下第i个物品时,遍历第i个物品是否被选择,选择其中值较大者.
2.3 计算
略
2.4 构造最优解
m[n][C]m[n][C]m[n][C]即为所求
3. 代码
模板题: http://acm.hit.edu.cn/contest/177/problem/E (好像只有我自己能打开, 留给自己复习用吧, 反正也没人看)
#include<stdio.h>
int v[101];
int w[101];
int m[101][10001];
int max(int x, int y) {
return (x > y ? x : y);
}
int main() {
int t, tt;
scanf("%d", &t);
for (tt = 1; tt <= t; tt++) {
int n, c;
scanf("%d %d", &n, &c);
int i, j;
for (i = 1; i <= n; ++i) {
scanf("%d %d", w + i, v + i);
}
for (i = 1; i <= n; ++i) {
for (j = 0; j <= c; ++j) {
if (i == 1 && j < w[i])
m[i][j] = 0;
else if (i == 1 && j >= w[i])
m[i][j] = v[i];
else if (i > 1 && j < w[i])
m[i][j] = m[i - 1][j];
else
m[i][j] = max(m[i - 1][j], m[i - 1][j - w[i]] + v[i]);
}
}
printf("Case #%d: %d\n", tt, m[n][c]);
}
}