动态规划——背包问题

一个背包最大容量为target, 有一些物品重量分别是2,2,4,6,3,利用动态规划得出背包中可以装下的最大重量。

首先建立一个二维矩阵作为动态规划的状态转移矩阵。每一个代码代表放每个重量的物品,每一列代表背包当前的重量。

 0123456789
21010000000
21010100000
41010101010
61010101010
31010111

1

11

背包中放入该物品则状态转移矩阵对应重量置为1.

def bag(items_info, capacity):
    n = len(items_info)
    memo = [[-1] * (capacity + 1) for i in range(n)]
    memo[0][0] = 1
    if items_info[0] <= capacity:
        memo[0][items_info[0]] = 1
        
    for i in range(n):
        for cur_weight in range(1, capacity+1):
            if memo[i-1][cur_weight] != -1:
                memo[i][cur_weight] = 1
                if cur_weight + items_info[i] <= capacity:
                    memo[i][cur_weight+items_info[i]] = 1
    for w in range(capacity, -1, -1):
        if memo[-1][w] != -1:
            return w

 

def bag(weights, target):
    m, n = len(weights), target + 1
    table = [[0] * n for _ in range(m)]
    
    # 处理第一行
    table[0][0] = 1
    if target >= weights[0]:
        table[0][weights[0]] = 1
    
    for i in range(1, m):
        for j in range(n):
            cur_weight = weights[i]
            if table[i-1][j] != 0:
                table[i][j] = table[i-1][j]
                if j + cur_weight <= target:
                    table[i][j + cur_weight] = 1
        
    print(table)
    
    for i in range(n-1, 0, -1):
        if table[-1][i] == 1:
            return i
    

bag([2,2,4,6,3], 9)

9

在原有基础上增加每个物品的重量:

def bagValue(items, target):
    m, n = len(items), target + 1
    table = [[0] * n for _ in range(m)]
    
    table[0][0] = 0
    if items[0][0] <= target:
        table[0][items[0][0]] = items[0][1]
        
    for i in range(1, m):
        for cur in range(target):
            if table[i-1][cur] != 0:
                table[i][cur] = table[i-1][cur]
                if cur + items[i][0] <= target:
                    table[i][cur + items[i][0]] = max(table[i-1][cur + items[i][0]], table[i][cur] + items[i][1])
    
    print(table)
    
    for i in range(n-1, 0, -1):
        if table[-1][i] != 0:
            return table[-1][i]

items_info = [(3,5), (2,2), (1,4), (1,2), (4,10)]
capacity = 8
print(bagValue(items_info, capacity))

19

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值