92. 背包问题

92. 背包问题

中文English

在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]

样例

样例 1:
	输入:  [3,4,8,5], backpack size=10
	输出:  9

样例 2:
	输入:  [2,3,5,7], backpack size=12
	输出:  12
	

挑战

O(n x m) time and O(m) memory.

O(n x m) memory is also acceptable if you do not know how to optimize memory.

注意事项

你不可以将物品进行切割。

 
 
输入测试数据 (每行一个参数)如何理解测试数据?
#对于这种拿了不能再拿的问题
class Solution:
    '''
    大致思路:
    1.重点,dp[i][j] = dp[i - 1][j - A[i - 1] or dp[i][j]
    对于当前拿的物品A[i - 1]是满足的,所以只需要判断上一次拿j - A[i - 1]是否满足,如果也满足,则为True
    
    对于上一次已经拿了j重量,则此次(上一次 + 1次)也满足,A[i][j] = A[i - 1][j] ,上一次为True,此次也为True
    
    2.对于拿了不能再拿的问题,依次拿每个物品,确保拿了不能在取
    
    3.边界情况,对于不管拿n次,0重量,都是满足True
    for i in range(len(A) + 1):
        dp[i][0] = True 
        
    4.对于背包0物品,则最多可以拿的重量是0, 返回0重量即可
    '''
    def backPack(self,m,A):
        l = len(A)
        if l == 0:return 0 
        
        #初始条件
        res = 0 
        dp = [[False]*(m + 1) for _ in range(l + 1)]#最多可以拿l次
        
        #边界情况,对于只拿0重量的话,则都满足为True
        for i in range(l + 1):
            dp[i][0] = True
        
        #对于只拿0次,则直接返回0重量,不用循环
        
        #计算顺序
        for i in range(1, l + 1):
            for j in range(m + 1):
                #如果上一次已经拿了j重量,则此次一样满足,如果上一次没有拿j重量,此次也为False
                dp[i][j] = dp[i - 1][j]
                
                #当前拿的物品是A[i - 1],注意是从0开始算第一个的
                if (j - A[i - 1] >= 0):#对于当前j总重量为5,当前拿的物品重量也为5,也是满足的
                    #此次拿A[i - 1],这个是满足的,如果上一次j - A[i - 1]也是满足,则此次拿j为True,否则False,只要有一次满足即可,此次均可以拿j重量
                    dp[i][j] = dp[i - 1][j - A[i - 1]] or dp[i][j]
                
        
        #取出拿最后一次的时候,满足的最大重量是多少,循环到后面重量越大,True则更新,只最后循环一次最后的数组即可
        for z in range(m + 1):
            if dp[l][z] == True:
                res = z
            
        return res 
                    
                    
                

 

posted @ 2020-06-21 12:11  风不再来  阅读(209)  评论(0编辑  收藏  举报