背包问题

背包问题:0-1背包问题,完全背包问题,多重背包问题

0-1背包问题:

有一个容量为V的背包和N个物品。这些物品有两个属性,体积wt[i]和价值val[i],每种物品只有一个。要求背包内装下尽可能多的物品使背包内物品总价值最大。背包可以不装满。

这是一道典型的动态规划的问题。

对于第i个物品只有两个状态,要么装进背包,要么不装。

对于背包的容量有V个状态,从0-V

所以在动态规划当中我们需要转移的状态需要有两个变量,用dp[i][j]表示当装前i个物品,背包容量为j时背包能够达到的最大总价值,i表示第i个物品,j表示此时背包的容量。

首先设置初始状态dp[i][j]  i∈[0,N] j∈[0,V]  dp[0][0-V]=0  dp[0-N][0]=0

接下来看状态转移方程。

如果第i个物品不装进背包,那么状态转移方程为 dp[i][j] = dp[i-1][j]。这个很容易理解,如果第i个物品没有装,那么背包内的总价值就等于前i-1个物品在背包内的总价值。

如果第i个物品装进背包,此时的状态转移方程为 dp[i][j] = dp[i-1][j-wt[j]]。理解的重点在于 j-wt[j] ,因为要装体积为 wt[j]的物品,而背包的容量为j,如果背包剩余的容量不到w[j]了,那么肯定是放不下的。要保证书包能够放下w[j]的物品,我们就要确保书包中已经装了的体积是小于等于 j -wt[j] ,这样才能装进体积为 j 的书包中。

def beibao(self,W,wt,val):
        '''
        背包问题,如果装物品使得背包中物品的价值最大
        :param W: 背包容量
        :param wt:物品的重量数组
        :param val:物品价值数组
        :return:
        '''
     N = len(wt)
     dp = [[0]*W for _ in range(len(N))]
     for i in range(N):
         for j in range(W):
             if wt[i]<=j:
                 dp[i][j] = max(dp[i-1][j-wt[i]]+val[j],dp[i-1][j])
             else:
                 dp[i][j] = dp[i-1][j]
     return dp[-1][-1]    

 

未完待续

(完全背包问题,多重背包问题)

 

def beibao(self,W,wt,val):
'''
背包问题,如果装物品使得背包中物品的价值最大
:param W: 背包容量
:param wt:物品的重量数组
:param val:物品价值数组
:return:
'''
N = len(wt)
dp = [[0]*W for _ in range(len(N))]
for i in range(N):
for j in range(W):
if wt[i]<=j:
dp[i][j] = max(dp[i-1][j-wt[i]]+val[j],dp[i-1][j])
else:
dp[i][j] = dp[i-1][j]
return dp[-1][-1]
posted @ 2020-09-07 14:48  扁鹊小脑  阅读(240)  评论(0编辑  收藏  举报