01背包问题
假设你是一名经验丰富的探险家,背着背包来到野外进行日常探险。天气晴朗而不燥热,山间的风夹杂着花香,正当你欣赏这世外桃源般的美景时,突然,你发现了一个洞穴,这个洞穴外表看起来其貌不扬,但凭借着惊为天人的直觉,这个洞穴不简单。于是,你开始往洞穴内探索,希望能发现一些有意思的东西。终于,皇天不负有心人,你在洞穴的尽头,发现了一堆珠宝,凭借你惊人的阅历,一眼便看出了它们各自的价值,心想着下下下下下下下下半辈子都有着落了。然而,天有不测风云,正准备将它们收入囊中,却不小心触碰到一个防御机关,洞穴马上就要崩塌了。在此危机时刻,你只有一个背包,你必须尽快做出抉择,从中选择最值钱的珠宝塞到你的背包,让背包中珠宝的总价值最大。好了好了,啰里啰嗦了大半天,我还是来精简一下问题吧。简而言之,你只有一个容量有限的背包,总容量为c,有n个可待选择的物品,每个物品只有一件,它们都有各自的重量和价值,你需要从中选择合适的组合来使得你背包中的物品总价值最大。问题分析:那还不简单,不管是什么,先往背包里塞,塞满赶紧走,狗命要紧,狗命要紧。。。好了好了,开个玩笑,言归正传。简单起见,我们来将上面的问题具体化,举一个更具体的栗子:假设有4个物品,它们的价值(v)和重量(w)如下图:
背包总容量为10,现在要从中选择物品装入背包中,要求物品的重量不能超过背包的容量,并且最后放在背包中物品的总价值最大。emmm,等等,为什么叫做0/1背包呢?为什么不叫1/2背包,2/3背包???仔细想想,这里每个物品只有一个,对于每个物品而言,只有两种选择,盘它或者不盘,盘它记为1,不盘记为0,我们不能将物品进行分割,比如只拿半个是不允许的。这就是这个问题被称为0/1背包问题的原因。所以究竟选还是不选,这是个问题。让我们先来体验一下将珠宝装入背包的感觉,为了方便起见,用xi代表第i个珠宝的选择(xi = 1 代表选择该珠宝,0则代表不选),vi代表第i个珠宝的价值,wi代表第i个珠宝的重量。于是我们就有了这样的限制条件:
我们的初始状态是背包容量为10,背包内物品总价值为0,接下来,我们就要开始做选择了。对于1号珠宝,当前容量为10,容纳它的重量2绰绰有余,因此有两种选择,选它或者不选。我们选择一个珠宝的时候,背包的容量会减少,但是里面的物品总价值会增加。就像下面这样:
这样就分出了两种情况,我们继续进行选择,如果我们选择了珠宝1,那么对于珠宝2,当前剩余容量为8,大于珠宝2的容量3,因此也有两种选择,选或者不选。
现在,我们得到了四个可能结果,我们每做出一个选择,就会将上面的每一种可能分裂成两种可能,后续的选择也是如此,最终,我们会得到如下的一张决策图:
这里被涂上色的方框代表我们的最终待选结果,本来应该有16个待选结果,但有三个结果由于容量不足以容纳下最后一个珠宝,所以就没有继续进行裂变。然后,我们从这些结果中,找出价值最大的那个,也就是13,这就是我们的最优选择,根据这个选择,依次找到它的所有路径,便可以知道该选哪几个珠宝,最终结果是:珠宝4,珠宝2,珠宝1。简单的看,对于每个物品,无外乎两种可能:选,或者不选。不选的话,背包的容量不变,最大价值还是之前的价值;选的话,背包的容量变小,价值变大。最优方案就是比较这两种方案,哪个会更好些:
**
01背包问题
[算法分析]
定义状态∶dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值w[i]第i件物品的重量,c背包总容量,j表示背包实时容量,也就是0到c之间的容量,v[i]第i件物品的价值如果w[i]>j:放不下,最大价值为i-1件物品讨论时的最大价值,即dp[i-1][j];如果w[i]<=j:放得下:
选上: 剩余容量:j-w[i],最大价值:v[i] + (i-1件物品,容量在j- w[i]的情况下最大价值),即v[i]+dp[i-1][j-w[i]];不选: 最大价值:i-1件物品讨论时的最大价值,即dp[i-1][j];所以动态转移方程:dp[i][j]=max(dp[i-1][j],v[i]+