背包问题

背包问题

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

题目:

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

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

对于每种物品策略:取 ||  不取

l  f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+v[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 //第几件物品

    for v=V..0 //装入前i件物品,背包容量为v时的最大价值

        f[v]=max{f[v],f[v-c[i]]+w[i]};

初始化:

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

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

 

2、完全背包

题目描述:

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

特点:物品可以重复取

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

l  f[i][v]=max(f[i-1][v-c[i]*k]+k*w[i],0<=k*c[i]<=V)

代码描述:

for i=1..N
    for v=0..V 
        f[v]=max{f[v],f[v-cost]+weight}: 

 

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 
struct Good{  
 int c,w;  
};  
Vector<Good>good;  
for(int i=1;i<=n;i++){  
  cin>>c>>w;  
   for(k=1;k<=s;k=k*2){  
     s-=k;  
     push_back(c*k,w*k);  
   }  
for(auto good:goods)//对于goods中的每一个物体
  for(int j=m;j>=good.c;j++)
    f[j]=max(f[j],f[j-good.c]+good.w); 
 

 

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

    for v=V..0

        for 所有的i属于组k

            f[v]=max{f[v],f[v-c[i]]+w[i]}

 

7、有依赖的背包问题

题目描述:

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

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

 

posted @ 2019-09-27 09:25  SUHANG苏航  阅读(153)  评论(0编辑  收藏  举报