Loading

三类基础的背包问题

背包问题

最基础的背包问题包含以下三个子问题:

  • 0-1背包问题:N个物品和一个容量为C的背包,第i件物品消耗的容量为\(C_i\),价值是\(W_i\),求放入哪些物品可以使得总价值\(V\)最大
  • 完全背包问题:有N种物品和一个容量为C的背包,每种物品都有无限件可用,第i件物品消耗的容量为\(C_i\),价值为\(W_i\),求解放入哪些物品可以使得背包中总价值\(V\)最大
  • 多重背包问题:有N种物品和一个容量为C的背包,第i种物品最多有\(M_i\)件可用,每件物品消耗的容量为\(C_i\),价值为\(W_i\),求解入哪些物品可以使得背包中总价值\(V\)最大。

这三种问题的相同之处就是:背包容量,背包的容量是一个有限的的数字,而我们需要在这个限制下找到可以使背包价值最大的方案。其中0-1背包是其他背包问题的基础,其他的问题都可以通过转换为0-1背包问题来解决。在完全背包问题中,虽然每种物品都可以选择无限个,但由于背包容量有限,实际上每种物品可以选择的数量也是有限的,那么将每种物品都看做是 V/Ci 种只有一件的不同物品,不就成了01背包问题吗?对于多重背包也是如此,只是每种物品的膨胀数量变成了 min{Mi, V/Ci}。

下面我们来看一下各个问题的状态转移方程

状态转移方程

0-1背包问题

任何一个物品,都有装或者不装两个选项。如果我们装这个物品的话,那么背包剩余的容量减去这个物品消耗的容量;如果不装这个物品的话,背包剩余容量则不发生变化。同时,物品是否装入也会影响背包携带的物品的总价值。那么状态转移方程就如下所示:

其中V[i,j]表示将前i件物品装进限重为j的背包可以获得的最大价值, 0<=i<=N, 0<=j<=C

V[i,j]=max(V[i-1,j],V[i-1,j-W[i]]+W[i])

完全背包问题

完全背包的状态转移方程如下所示:

V[i,j]=max(V[i-1,j-kCi] + kWi | 0 <= kCi <=j)

其中\(k\)是一个需要遍历的参数,表示装入的个数

多重背包问题

V[i,j]=max(V[i-1,j-kC[i]] + kW[i] | 0<=k<=M[i]&&0<=kC[i]<=j )

与完全背包类似,此时\(k\)依然是一个需要遍历的常数。另外需要同时满足:

  1. 装入的物品个数不可以超出背包的容量
  2. 装入的物品个数不可以超出物品本身的个数

这两个要求

伪代码(二维)

0-1背包问题

initial: V[0,:]=0,V[:,0]=0
for i=1:(n-1) :
    for j=W[i]:(C-1):
        V[i,j]=max(V[i-1,j],V[i-1,j-W[i]]+W[i] | j-W[i]>=0)

时间复杂度:O(cn)

空间复杂度:O(cn)

完全背包问题

initial: V[0,:]=0,V[:,0]=0
for i=1:(n-1) :
    for j=W[i]:(C-1):
        for k satisfy that 0 <= kC[i] <=j:
        	V[i,j]=max(V[i-1,j],V[i-1,j-kW[i]]+kW[i])

时间复杂度:O(kcn)

空间复杂度:O(kcn)

多重背包问题

initial: V[0,:]=0,V[:,0]=0
for i=1:(n-1) :
    for j=W[i]:(C-1):
        for k satisfy that 0 <= kC[i] <=j&&0<=k<=M[i]:
        	V[i,j]=max(V[i-1,j],V[i-1,j-kW[i]]+kW[i])

时间复杂度:O(kcn)

空间复杂度:O(kcn)

posted @ 2022-03-28 15:02  晓哥爱咖啡  阅读(99)  评论(0编辑  收藏  举报