动态规划——0/1背包问题
为了更好地介绍动态规划的思想,在这里我以0/1背包问题为例,具体的为大家解释动态规划求解问题的步骤。
一、0/1背包问题
给定n个重量为w1,w2,w3,…,wn,价值为p1,p2,p3,…,pn的物品和容量为capacity的背包,求这个物品中一个最有价值的子集,使得在满足背包的容量的前提下,包内的总价值最大
0-1背包问题指的是每个物品只能使用一次.
在这里我们可以定义B(i, j),表示考虑从第一件到底 i 件物品,在背包承重为 j 的条件下能拿到的最大价值。
我们将capacity = 8,n=4,即共4件物品,其重量与价值如下表:
最终的为题即是求解B(4, 8)。
思路
通过简单的B(i, j)如B(0,0),B(0,1)来计算更复杂的B(i, j),直到计算出B(4, 8)。
在这里我们可以得出一个递推公式:
在这里用一个二维数组来保存B(i, j):
那么我们在这里就可以用一个二维数组来实现上图的表格:
w = [0,2,3,4,5] # 物品重量 p = [0,1,2,5,6] # 物品价值 n_item = len(w)-1 # 物品个数 capacity = 8 # 背包可承受的重量 table = [[0 for column in range(capacity+1)] for row in range(n_item+1)]# 遍历二维数组 for i in range(1,n_item+1): for j in range(1,capacity+1): if j < w[i]: table[i][j] = table[i-1][j] else: table[i][j] = max(table[i-1][j],table[i-1][j-w[i]]+p[i]) for i in table: print(i)
可以得到结果如下: