01背包的问题是背包问题中最基础的,也是学习其他背包类型的前提,新手的时候被背包折磨地死去活来,理解了很久,才慢慢明白其中的原理。因此打卡留个纪念。
话说有一个给定容量大小capacity的背包,以及一堆物品,每一个物品都有其对应的重量weight和value,为什么是weight,我也不知道。别人都是这么写的,就把weight当做体积来看吧。问对于给定容量的这个背包,能够装下的物品的最大的价值value是多少?
物品编号 | weight | value |
1 | 1 | 15 |
2 | 3 | 20 |
3 | 4 | 30 |
假如我们把物品放成一排,从左往右开始取。对于给定的容量capacity,我们再依次用1,2,3,....capacity去尝试装每一件物品,看看能否装的下,即计算出每一个容量状态下的背包最大价值,以此推算出状态转移方程。对于当前的一个重量为w,,价值为v的物品,如果我们此刻试探它的容量c1小于w,那么对于当前这个物品我们肯定是拿不了,因为背包全空也装不下。如果我们试探它的容量c1>=w,那么对于当前物品,我们当然可以选择拿,或者不拿。那我们该怎么判断拿还是不拿呢?
很简单。我们可以保证,当前物品的w一定小于等于此时我们尝试的背包容量c1。如果我们选择拿当前物品的话,背包里就要有w的空间是留给当前物品的,即用我们背包的容量c1减去当前物品的重量,即c2=c1-w,我们可以保证得到的这个c2一定是大于或等于0的,因为我们在进行这一步的前提就是物品的w一定小于等于此时我们试探的背包的容量c1。 意思是在背包里预留出了当前物品的位置,c2表示的是当用我们一开始的试探容量减去预留出当前物品的容量之后,背包里的剩余容量。其实也就是指放下当前物品之前状态的背包容量。要注意的是,当前c2的空间不一定全部装满了,也有可能有一部分多余的空间,但是这个无所谓(当初就这里很不理解)。然后我们再用预留出位置之后的背包里的物品价值+当前物品的价值,与预留出位置之前背包里的物品价值比较,如果前者大于后者,说明我们这一操作有效,因此我们选择拿当前这