一维数组循环
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
https://zhuanlan.zhihu.com/p/78060568
1) input:
4 5 物品总数 不超过总重量
1 2 重量 价值
2 4
3 4
4 5
output:
8
https://en.wikipedia.org/wiki/Knapsack_problem
2) input:
10 67
23 505
26 352
20 458
18 220
32 354
27 414
29 498
26 545
30 473
27 543
output:
1270
"""
# 01背包问题 利用一维数组进行
a = raw_input()
n, m = list(map(int, a.split()))
w = [0 for i in range(n + 1)]
v = [0 for i in range(n + 1)]
for i in range(1, n + 1):
b = raw_input()
w[i], v[i] = list(map(int, b.split()))
# 定义一个数组 f[j] 表示容量为j的情况下能放的总价值最大
f = [0 for i in range(m + 1)]
# print(f)
for i in range(1, n + 1):
for j in range(m, 0, -1): # 容量从大到小遍历
if j >= w[i]:
f[j] = max(f[j], f[j - w[i]] + v[i])
else:
break
# j为容量不断上升 当容量大于当前的时候才可以放下这个
print(f[-1])
递归计算
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
https://en.wikipedia.org/wiki/Knapsack_problem
input:
10 67
23 505
26 352
20 458
18 220
32 354
27 414
29 498
26 545
30 473
27 543
output:
1270
"""
a = raw_input()
n, W = list(map(int, a.split()))
w = [0 for i in range(n + 1)]
v = [0 for i in range(n + 1)]
for i in range(1, n + 1):
b = raw_input()
w[i], v[i] = list(map(int, b.split()))
# 二维数组暂存,一维是物品数个list,每个list里是重量0到最大个值,表示前i个物品在重量限制值时的最大值
value = [[-1 for i in range(W + 1)] for j in range(n + 1)]
def max_value(i, j):
"""
Define function m so that it represents the maximum value we can get under the condition:
use first i items, total weight limit is j
:param i: 物品数量
:param j: 最大重量值
:return: 达到最大重量值时,最大价值
"""
if i <= 0 or j <= 0:
value[i][j] = 0
return 0
# has not been calculated, we have to call function
if value[i - 1][j] == -1:
value[i - 1][j] = max_value(i - 1, j)
# item cannot fit in the bag
if w[i] > j:
value[i][j] = value[i-1][j]
else:
# value[i-1][j-w[i]] has not been calculated, we have to call function
if value[i-1][j-w[i]] == -1:
value[i - 1][j - w[i]] = max_value(i-1, j-w[i])
# 包可以容纳下当前第i个物品,这样,前i个物品在重量限制j时的最大价值为
# 就是比较下面,取最大值
# 1. 前i-1个物品满载,达到包容量时的最大价值
# 2. 前i-1个物品,且重量刚好可以容纳第i个物品而没有容纳时,的最大价值加上此时第i个物品的价值之和
value[i][j] = max(value[i-1][j], value[i-1][j-w[i]]+v[i])
return value[i][j]
print max_value(n, W)
print value
使用dict优化上面递归时的数组存储
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
https://en.wikipedia.org/wiki/Knapsack_problem
input:
10 67
23 505
26 352
20 458
18 220
32 354
27 414
29 498
26 545
30 473
27 543
output:
1270
"""
a = raw_input()
n, W = list(map(int, a.split()))
w = [0 for i in range(n + 1)]
v = [0 for i in range(n + 1)]
for i in range(1, n + 1):
b = raw_input()
w[i], v[i] = list(map(int, b.split()))
value = {
}
def get_value(a, b):
if value.get(a) is None:
return -1
if value.get(a).get(b) is None:
return -1
# print "get %s,%s val %s" % (a, b, value.get(a).get(b))
return value.get(a).get(b)
def set_value(a, b, val):
if value.get(a) is None:
value[a] = {
}
# print "set %s,%s to %s" % (a, b, val)
value.get(a)[b] = val
def max_value(i, j):
"""
Define function m so that it represents the maximum value we can get under the condition:
use first i items, total weight limit is j
:param i: 物品数量
:param j: 最大重量值
:return: 达到最大重量值时,最大价值
"""
if i <= 0 or j <= 0:
set_value(i, j, 0)
return 0
# has not been calculated, we have to call function
if get_value(i-1, j) == -1:
set_value(i-1, j, max_value(i-1, j))
# item cannot fit in the bag
if w[i] > j:
set_value(i, j, get_value(i-1, j))
else:
# value[i-1][j-w[i]] has not been calculated, we have to call function
if get_value(i-1, j-w[i]) == -1:
set_value(i-1, j-w[i], max_value(i-1, j-w[i]))
# 包可以容纳下当前第i个物品,这样,前i个物品在重量限制j时的最大价值为
# 就是比较下面,取最大值
# 1. 前i-1个物品满载,达到包容量时的最大价值
# 2. 前i-1个物品,且重量刚好可以容纳第i个物品而没有容纳时,的最大价值加上此时第i个物品的价值之和
set_value(i, j, max(get_value(i-1, j), get_value(i-1, j-w[i])+v[i]))
# print "%s,%s max return %s" % (i, j, get_value(i, j))
return get_value(i, j)
print max_value(n, W)
print value