我昨天深夜刚到家,昨天早上我还在收拾行李。因为我家比学校要冷得多,所以我要尽可能多带衣服回去,严格来说应该是保证装入背包的衣服的总体积最大(毕竟体积越大也就是厚度越大,越暖和嘛),那么我要选择哪些衣服装入背包呢?

分析问题

衣服只有两种状态,要么装入背包,要么不装,既然如此那就太简单了,这不就是传说中的01背包问题吗?实际上并不完全是之前接触的01背包问题,之前的01背包问题是这样的:有n个物品,第i个物品的重量是w[i],价值是v[i],背包最大载重为c,装入哪些物品可以使总价值最大?对我来说我完全可以把价值换成体积一样去处理,到底哪里不一样?是因为背包最大容量有限制啊,体积不能做到越大越好!这可咋办?实际上很简单,我只需要先假设背包体积无上限,重量有上限,把价值换成体积,当做之前接触过的01背包问题,使用动态规划求解。因为动态规划是不断地填表,这个表中的每一个解都是子问题的最优解。我只需要在这个表中筛选出来一个值,这个值满足两个条件:1.最接近背包最大容量。2.没有超过背包最大容量。我之所以要使用这种很简单的方法,是因为如果我把体积也考虑进去它就变成了一个三维01背包问题,就需要一个三维的表来存放最优解了,空间复杂度n3

解决问题

这个问题总共分为两大步,先解决01背包问题,然后再去筛选符合条件的最优解。下面我们先来看01背包问题。

01背包问题

01背包问题的解决方式有很多种:动态规划,回溯……在这里因为背包最大载重和衣服数量比较小,使用动态规划是可以的,空间上不会耗费太多。

用动态规划求解01背包问题很简单,就一个公式:f[i, j] = max{f[i-1, j-w[i]]+v[i](j >= w[i]),  f[i-1, j]}

f[i, j]表示在前i件衣服中选择若干件放在承重为j的背包中,可获取的最大体积,w[i]是第i件衣服的重量,v[i]是第i件衣服的体积。问题变成了为了保证总体积的最大化,第i件衣服要不要装入背包?下面我来根据我当时的情况,简单的举个例子。

假设我当时共有a,b,c,d,e这5件衣服,它们的重量分别是2,2,6,5,4,它们的体积分别是6,3,5,4,6,现在给你个承重为10的背包,怎么装背包,可以保证体积最大。

为了方便大家理解,下面先来结合公式手工填表(要填两张表,一个是最优值表,一个是最优决策表),首先要明确的是这个表是自上向下,自左向右的。直接给出答案,填表的过程我就不详细讲解了,因为太繁琐了。

name

weight

volume

1

2

3

4

5

6

7

8

9

10

a

2

6

0

6

6

6

6

6

6

6

6

6

b

2

3

0

6

6

9

9

9

9

9

9

9

c

6

5

0

6

6

9

9

9

9

11

11

14

d

5

4

0

6

6

9

9

9

10

11

13

14

e

4

6

0

6

6

9

9

12

12

15

15

15

name

weight

volume

1

2

3

4

5

6

7

8

9

10

a

2

6


a

a

a

a

a

a

a

a

a

b

2

3


a

a

ab

ab

ab

ab

ab

ab

ab

c

6

5


a

a

ab

ab

ab

ab

ac

ac

abc

d

5

4


a

a

ab

ab

ab

ad

ac

abd

abc

e

4

6


a

a

ab

ab

ae

ae

abe

abe

abe

找出符合条件的最优解

因为背包容量受到限制,所以并不是体积越大越好。假设背包容量为10,那么我们一眼就能够从第一个表中找出符合条件的值——就是10,然后就是对应到第二张表找到最优决策——ad!

今天的文章有不懂的可以加群,群号:822163725,备注:小陈学Python,不备注可是会被拒绝的哦~!


因收拾行李引发的01背包问题_01背包