Written with StackEdit.
Reference:https://leomalik.github.io/01%E8%83%8C%E5%8C%85%E3%80%81%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E3%80%81%E5%A4%9A%E9%87%8D%E8%83%8C%E5%8C%85.html
See Also: https://www.kancloud.cn/kancloud/pack/70128
之前提到了DP背包问题,很多文章都提到了可以转化为最简单的0/1背包求解.翻找了很多文章都不理想,找到了这一篇文章讲解的比较透彻,在这里写一些体会.
完全背包转化0/1
每件物品转换为
[
W
/
w
[
i
]
]
[W/w[i]]
[W/w[i]]件相同物体,其中W固定为输入的最大重量(考虑到最优解可能是只挑一种)
但这种算法并未优化时间复杂度.
把第i种物品拆成费用为
c
[
i
]
∗
2
k
c[i]*2^k
c[i]∗2k、价值为
w
[
i
]
∗
2
k
w[i]*2^k
w[i]∗2k的若干件物品,其中k满足c[i]*2^k<=V
.
这里是二进制的思想.
O
c
t
=
∑
(
0
/
1
)
×
w
e
i
g
h
t
Oct=\sum (0/1)\times weight
Oct=∑(0/1)×weight(这里Oct是最后选择的 总量
示例:
Weight=16,Value=12,Maxweight=100
分解为如下:
(16,12)
(32,24)
(64,48)
多重背包转化
基准方式:
每个物品有k个,则分解为k个单独物品(并没什么用)
改进方式:依然使用二进制.
拆分为
w
e
i
g
h
t
=
w
[
i
]
∗
2
k
,
v
a
l
u
e
=
v
[
i
]
∗
2
k
weight=w[i]*2^k,value=v[i]*2^k
weight=w[i]∗2k,value=v[i]∗2k的物品,要求
w
e
i
g
h
t
≤
m
a
x
w
e
i
g
h
t
weight\leq maxweight
weight≤maxweight且
2
k
+
1
−
1
≤
m
a
x
q
u
a
n
t
i
t
y
2^{k+1}-1\leq maxquantity
2k+1−1≤maxquantity(为了保证全选依然可行).