python递归-背包

递归代码Ⅰ:

w = [0, 2, 3, 4, 5, 9]
v = [0, 3, 4, 8, 8, 10]
max_W = 20
sum = {(i, w1):0 for i in range(len(w))
                    for w1 in range(max_W+1)}   
                    # python对数据操作的实现很容易


def m(i, W):  # 第i个物品怎么放
    if i == 0:
        sum[(i, W)] = 0
        return 0
    elif W == 0:
        sum[(i, W)] = 0
        return 0
    elif sum[(i, W)] != 0:
        return sum[(i, W)]
    elif w[i] > W:
        sum[(i, W)] = m(i-1, W)
        return sum[(i, W)]
    else:
        sum[(i, W)] = max(m(i-1, W), v[i] + m(i-1, W-w[i]))
        return sum[(i, W)]

       

for i in range(1, len(w)):  # 填满记忆数组
    for j in range(1, max_W+1):
        m(i, j)
for i in range(1, len(w)):
    for j in range(1, max_W+1):
        print(i, '-', j, ':', sum[(i, j)])
print(sum[(len(w)-1, max_W)])  # 注意索引

递归代码Ⅱ:

tr = {(2, 3), (3, 4), (4, 8), (5, 8), (9, 10)}
val = {}

def thief(tr, m):
    if tr == set() or m == 0:
        val[(tuple(tr), m)] = 0  
        return 0
    
    elif (tuple(tr), m) in val:  # 记忆
        return val[(tuple(tr), m)]

    else:
        vmax = 0
        for t in tr:  # 取出一个合适的宝物再求处剩下宝物的最大值    
            if t[0] <= m:
                vmax = max(vmax, t[1] + thief(tr-{t}, m-t[0]))
        val[(t, m)] = vmax
        return vmax
        
# 秀
print(thief(tr, 20))

迭代

# 从小到大讨论
tr = [None, {'w':2, 'v':3}, {'w':3, 'v':4},
            {'w':4, 'v':8}, {'w':5, 'v':8},
            {'w':9, 'v':10}]
max_m = 20
val = {(i, w):0 for i in range(len(tr))
                    for w in range(max_m+1)}

for i in range(1, len(tr)):  # 从小到大递推,由于tr的第一项是None,因此得从第一项开始,range[1, len(tr)]
    for w in range(1, max_m+1):
        if tr[i]['w'] > w:  # 注意:这里不是max_m
            val[(i, w)] = val[(i-1), w]
        else:
            val[(i, w)] = max(val[(i-1), w], tr[i]['v'] + val[(i-1), w-tr[i]['w']]) 

print(val[(len(tr)-1, max_m)])
原文地址:https://www.cnblogs.com/SKEZhi/p/13361200.html