背包问题

匿名 (未验证) 提交于 2019-12-03 00:11:01

背包问题

1、0-1背包(f[v]表示容量为v的背包的最大价值)

题目:

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

特点:每个物品只可取一次

不放第i 件物品的价值:f[i-1][v],问题转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];

放入第i 件物品的价值:f[i-1][v-c[i]]+v[i], 问题转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”

主体代码:

for i=1..N //第几件物品

初始化:

若要求恰好装满背包:将f[0]初始化为0,其余f[1…N]初始化为-∞,此时只有f[0]的初始值是有意义的,其余的背包都无意义

若不要求装满,值需要得到最大价值的背包:将f[0…N]都初始化为0

2、完全背包

题目描述:

有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

特点:物品可以重复取

对于每种物品策略:取0次、 取1次、2次…

代码描述:

for i=1..N
 
 

3、多重背包

题目描述:

有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

特点:可重复取,但每种物品取的次数固定

解题策略:将每个物品可取的次数n[i]分成不同n份,放入背包,变成0-1背包问题。分组时,可以将每个n分为几个数,使0-n中的每个数都可以由这些数组合得到。(如:10可以由:1 2 4 3组合得到)

代码描述:

//n个物品,背包容量为m 
 
 
 
 
 
 
 
 
 
 
 
for(auto good:goods)//对于goods中的每一个物体
 
 
 

4、混合背包问题

判断当前物品属于哪一类,分别用不同背包问题的解决方案

解题策略:顺序:0-1背包、多重背包、完全背包

5、二维费用背包问题

题目描述:

二维费用的背包问题是指:对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价;对于每种代价都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。设这两种代价分别为代价1和代价2,第i件物品所需的两种代价分别为a[i]和b[i]。两种代价可付出的最大值(两种背包容量)分别为V和U。物品的价值为w[i]。

特点:背包的限制增加一维

要点:状态增加一维,增加一维循环

f[i][v][u]=max{f[i-1][v][u],f[i-1][v-a[i]][u-b[i]]+w[i]}

6、分组背包问题

题目描述:

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

特点:与0-1背包问题类似

要点:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值

状态转移方程:

f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于组k}

核心代码实现:

for 所有的组k

7、有依赖的背包问题

题目描述:

这种背包问题的物品间存在某种“依赖”的关系。也就是说,i依赖于j,表示若选物品i,则必须选物品j。为了简化起见,我们先设没有某个物品既依赖于别的物品,又被别的物品所依赖;另外,没有某件物品同时依赖多件物品。

解题策略:把每一个主件和它所有附件的集合当成一个背包问题,求出每一个主件选择的最优解,再把已经是最优搭配所有的选择构成一个背包问题,最初得出最后的最优解

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!