一个背包最大容量为target, 有一些物品重量分别是2,2,4,6,3,利用动态规划得出背包中可以装下的最大重量。
首先建立一个二维矩阵作为动态规划的状态转移矩阵。每一个代码代表放每个重量的物品,每一列代表背包当前的重量。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
2 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
4 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
6 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
3 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
背包中放入该物品则状态转移矩阵对应重量置为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