0-1背包问题
给定N种物品和一个背包,第i个物品的价值为vi,重量为wi,每个物品只能选择放入背包或者不放入背包,背包承重为c,求使得背包中物品价值最大的放法。
解法:动态规划
定义状态:c[i][m]表示考虑第i件物品( 1<=i<=n )放入与否时,背包容量(这里的容量就是指总容量,并不是指还能装的重量,而是包含背包中已经装了物品的和没装物品的部分,可以把背包想成由很多小背包组成)为m的状态下,可以获得的最大价值。
C[ i ][ m ] = max{ c[ i-1 ][ m ], c[ i-1 ][ m-wi ]+vi } (1<i<n && m>=wi)
= c[ i-1 ][ m ] (1<i<n && m<wi)
C[ 0 ][ m ] = 0;
c[ i-1 ][ m ]表示第i件物品没有放入背包状态下背包价值, c[ i-1 ][ m-wi ]+vi 表示第i件物品放入了背包状态下背包价值。
**0-1背包问题还有一种变种,就是要求背包必须装满状态下达到最高价值:这只需在初始化状态下做改变即可。
1 不需要装满条件下,C[0][x] (0<=x<=c)全部初始化为0
2 只能装满条件下,C[0][0]=0, C[0][i]( 1<=i<=c )初始化为 -∞,这样就使得当前背包没有装满的策略价值都是-∞。
背包问题
与0-1背包问题相类似,但不同的是在选择物品i时,可以一部分装进背包,不一定全部装入背包。
0-1背包问题 与 背包问题 都具有最优子结构性质;但是背包问题可以用贪心算法,0-1背包则不行。
解法:首先计算每件物品单位重量的价值vi/wi,然后依照贪心选择策略,将尽可能多的单位重量价值最高的物品放入背包。如果放完背包还有剩余,就放单位重量价值次高的物品。
完全背包问题
给定N种物品和一个背包,第i个物品的价值为vi,重量为wi,每个物品可以选择放0个,1个...n个到背包中,背包承重为c,求使得背包中物品价值最大的放法。
解法:由于完全背包问题也满足最优子结构,并且有重复子结构,所以使用动态规划的方法
定义状态:c[i][m]表示考虑第i件物品( 1<=i<=n )时,背包容量(这里的容量就是指总容量,可以把背包想成由很多小背包组成)为m的状态下,可以获得的最大价值。
C[i][m] = max{ c[ i-1 ][ m-k*wi ] + k*vi | 0<=k*wi<=c }
C[0][m] = 0
如果要装满一个重量刚好为value的背包,已知每种重量物品的数量。
可以假设每种物品的价格都为1,这样就转化为一定要装满背包的完全背包问题。