01背包
- 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
- 定义 F [ i , j ] F[i,j] F[i,j]为前 i i i个物体在上限为 V V V的情况下能获得的最大价值
- 由放或不放两个状态空间转移来
转 移 方 程 : F [ i , v ] = m a x ( F [ i − 1 , v ] , F [ i − 1 , v − C i ] + W i ) 转移方程:F[i,v] = max ( F[i − 1,v],F[i − 1,v − C i ] + W i ) 转移方程:F[i,v]=max(F[i−1,v],F[i−1,v−Ci]+Wi)
- 优化空间复杂度之后:
F
[
0..
V
]
←
0
F~[0..V ]←0
F [0..V]←0
f
o
r
i
←
1
t
o
N
for~ i ← 1 ~to~ N
for i←1 to N
f
o
r
v
←
V
t
o
C
i
~~~~for ~v ← V~ to~ C _i
for v←V to Ci
F [ v ] ← m a x ( F [ v ] , F [ v − C i ] + W i ) ~~~~~~~~F[v] ← max~( F[v],F[v − C_ i ] + W_ i ) F[v]←max (F[v],F[v−Ci]+Wi)
初始的 F [ 0.. V ] F[0..V] F[0..V] 意义为前0个物品在上限下的最大价值,因此为0.
完全背包
-
特点:有 N N N 种物品和一个容量为 V V V 的背包,每种物品都有无限件可用
-
定义 F [ i , j ] F[i,j] F[i,j]为前 i i i个物体在上限为 V V V的情况下能获得的最大价值
-
子状态空间为:对于第 i i i 种,不选,选1个,选2个…,选 ⌊ V v i ⌋ \lfloor \frac{V}{v_{i}} \rfloor ⌊viV⌋ 件
转移方程:
F
[
i
,
v
]
=
m
a
x
(
F
[
i
−
1
,
v
−
k
C
i
]
+
k
W
i
∣
0
≤
k
C
i
≤
v
)
F[i,v] = max ( F[i − 1,v − kC i ] + kW i | 0 ≤ kC i ≤ v )
F[i,v]=max(F[i−1,v−kCi]+kWi∣0≤kCi≤v)
优化时间复杂度:
F
[
i
,
v
]
=
m
a
x
(
F
[
i
−
1
,
v
]
,
F
[
i
,
v
−
v
i
]
)
F[i,v]=max( F[i-1,v],F[i,v-v_i] )
F[i,v]=max(F[i−1,v],F[i,v−vi])
推导:
- F [ i , v ] = m a x ( F [ i − 1 , v ] , F [ i − 1 , v − v i ] + w i , F [ i − 1 , v − 2 v i ] + 2 w i . . . . . ) F[i,v] = max (F[i-1,v],F[i-1,v-v_i]+w_i,F[i-1,v-2v_i]+2w_i.....) F[i,v]=max(F[i−1,v],F[i−1,v−vi]+wi,F[i−1,v−2vi]+2wi.....)
- F [ i , v − v i ] = m a x ( F [ i − 1 , v − v i ] , F [ i − 1 , v − 2 v i ] + w i , F [ i − 1 , v − 3 v i ] + 2 w i . . . . . ) F[i,v-v_i] = max (F[i-1,v-v_i],F[i-1,v-2v_i]+w_i,F[i-1,v-3v_i]+2w_i.....) F[i,v−vi]=max(F[i−1,v−vi],F[i−1,v−2vi]+wi,F[i−1,v−3vi]+2wi.....)
- 下界相同,因此 F [ i , v ] = m a x ( F [ i − 1 , v ] , F [ i , v − v i ] ) F[i,v]=max( F[i-1,v],F[i,v-v_i] ) F[i,v]=max(F[i−1,v],F[i,v−vi])
- 也可以结合 F [ i , v ] F[i,v] F[i,v] 二维矩阵理解
- 优化空间复杂度之后:
F
[
0..
V
]
←
0
F[0..V ]←0
F[0..V]←0
f
o
r
i
←
1
t
o
N
for~ i ← 1 ~to~ N
for i←1 to N
f
o
r
v
←
C
i
t
o
V
~~~~for ~v ← C_i ~to~ V
for v←Ci to V
F [ v ] ← m a x ( F [ v ] , F [ v − C i ] + W i ) ~~~~~~~~F[v] ← max(F[v],F[v − C_ i ] + W_ i ) F[v]←max(F[v],F[v−Ci]+Wi)
多重背包
-
特点:有 N N N 种物品和一个容量为 V V V 的背包。第 i i i 种物品最多有 s i s_ i si 件可用.
-
定义同上
-
子状态空间为:对于第 i i i 种,不选,选1个,选2个…,选 m i n ( ⌊ V v i ⌋ , s i ) min(\lfloor \frac{V}{v_{i}} \rfloor,s_i) min(⌊viV⌋,si) 件
转移方程:
F
[
i
,
v
]
=
m
a
x
(
F
[
i
−
1
,
v
−
k
∗
C
i
]
+
k
∗
W
i
∣
0
≤
k
≤
s
i
且
v
>
=
k
∗
C
i
)
F[i ,v] = max ~(F[i − 1,v − k ∗ C _i ] + k ∗ W _i~ |~ 0 ≤ k ≤ s_i 且v>= k ∗ C _i)
F[i,v]=max (F[i−1,v−k∗Ci]+k∗Wi ∣ 0≤k≤si且v>=k∗Ci)
转化为01背包求解
cin>>a>>b>>s;
int k=1;
while(s)
{
if(s>=k) v[++pos]=a*k,w[pos]=b*k,s-=k;
else v[++pos]=a*s,w[pos]=b*s,s=0;
k*=2;
}
此程序的作用是把 s s s 拆分成1,2,4… 2 k − 1 2^{k-1} 2k−1, s i − 2 k + 1 s_i-2^{k}+1 si−2k+1
可以组合出 1 1 1~ s i s_i si 的任一种可能
分组背包
-
特点:有 N N N 种物品和一个容量为 V V V 的背包。
这些物品被划分为 K 组,每组中的物品互相冲突,最多选一件。 -
定义 F [ i , j ] F[i,j] F[i,j]为前 i i i 组物体在上限为 V V V的情况下能获得的最大价值
-
子状态空间为:对于第 i i i 组,不选,选第1个,选第2个…,选第 k k k 个
转移方程:
F
[
k
,
v
]
=
m
a
x
(
F
[
k
−
1
,
v
]
,
F
[
k
−
1
,
v
−
C
i
]
+
W
i
∣
i
∈
g
r
o
u
p
k
)
F[k,v] = max(F[k − 1,v],F[k − 1,v − C_ i ] + W_ i | i ∈ group k)
F[k,v]=max(F[k−1,v],F[k−1,v−Ci]+Wi∣i∈groupk)
- 优化空间复杂度之后:
f
o
r
k
←
1
t
o
K
for~ k ← 1 ~to ~K
for k←1 to K
f
o
r
v
←
V
t
o
0
~~~~for~ v ← V ~to~ 0
for v←V to 0
f
o
r
a
l
l
i
t
e
m
i
i
n
g
r
o
u
p
k
~~~~~~~~for ~all~ item~ i ~in ~group ~k
for all item i in group k
F
[
v
]
←
m
a
x
(
F
[
v
]
,
F
[
v
−
C
i
]
+
W
i
)
~~~~~~~~~~~~F[v] ← max ( F[v],F[v − C i ] + W i )
F[v]←max(F[v],F[v−Ci]+Wi)
- 综上,为了优化空间复杂度且转移不被破坏,需要对 j j j的转移顺序进行分析