01背包:
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
思路 :
每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。
若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f [i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]
这里我们进行一维数组的讲解:
同上所说,我们对第i件物品决策时,只用考虑前i-1件物品的状态,因此我们可以只用一维数组,
伪代码如下:
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
这里,由于v是从大到小遍历的,v-c[i]则是前i-1个已经决策好的物品放入v-c[i]中的价值,若是从小到大遍历,则代表的是前i个物品放入v-c[i]中的价值,因为新加入的第i个物品会把前面的覆盖掉,相当于会多次选第i件物品,因为物品只有一个,所以不适用,但是在完全背包中是很便利的.
这里给大家一个表,大家可以手动填一下,就明白上文所说的含义了.
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
根据01背包的状态转换方程,需要考察两个值,
一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;
在这里,
f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6
由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包
完全背包:
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
这里和01背包不同的只是物品的件数由一件变成无限件,同上文所说,我们将V由V遍历到0变为由0遍历到V即转换成完全背包的解法.
本文详细介绍了01背包和完全背包问题的解决方法,包括状态转移方程及一维数组实现技巧,并通过实例帮助理解两种背包问题的差异。
1041

被折叠的 条评论
为什么被折叠?



