背包算法

问题:有n件物品,每件物品的重量是Wi(i=1,2,…n),物品的价值是Pi(i=1,2,…n),背包能承受的最大重量的T,问如何放置物品,可以使背包中的物品的价值最大?
想法:

最原始的想法:先找到物品的所有组合,共有2n -1个,然后遍历所有的组合,判断物品的质量是否<=T,这种算法的时间复杂度是O(2n+1),空间复杂度是O(2n).不管是时间复杂度还是空间复杂度都比较高,这种算法的可行度比较低,应该要找其他的解决办法

动态规划:我们可以把这个问题拆分成更小的问题,如果小问题解决了,大问题随之也就解决了。假设F[i-1][w]表示对于前i-1件物品来说背包中的物品的最大收益,那么对于第i件物品来说,就有2中可能,如果放第i件物品,则F[i][w] = max(F[i-1][w-w[i]] + p[i], F[i-1][w]);如果不放第i件物品,则F[i][w] = F[i-1][w] .我们需要计算出w为0,1,2,3…T时,背包的物品的收益
|n = 5 #物品的数量
w = [5,4,7,2,6] #每件物品的重量
p = [12,3,10,3,6] #每件物品的价值

物品\重量01234567891011
0000000000000
100001212121212121212
20000312121212151515
30000312121212151515
40033312121515151518
50033312121515151518
total = 11       #背包能容纳的重量
n = 5       #物品的数量
w = [5,4,7,2,6]         #每件物品的重量
p = [12,3,10,3,6]          #每件物品的价值

rest = [[0]*(total+1) for i in range(n+1)]      # 初始化一个二维数组,rest[i][w] (i=0,1,2,3,4,5   w=0,1,2,3,4,...11)
f = [0] * (total+1)


def pack():
    """
    :param n: 物品的数量
    :param total: 背包能容纳的重量
    """
    for i in range(1, n+1):
        for j in range(total+1):
            if w[i-1] > j:
                rest[i][j] = rest[i-1][j]
            else:
                if j-w[i-1] >= 0:
                    rest[i][j] = max(rest[i-1][j-w[i-1]]+p[i-1], rest[i-1][j])
    return rest


def pack_2():
    """
    优化空间复杂度之后的算法   O(total+1)
    :return: 
    """
    for i in range(1, n+1):
        for j in range(total, w[i-1]-1, -1):
            f[j] = max(f[j], f[j - w[i - 1]] + p[i - 1])

    return f




if __name__ == "__main__":
    rest = pack()
    print("rest: ", rest)

    rest = pack_2()
    print("pack_2: ", rest)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值