【动态规划】python实现01背包问题

题目1:
第一行两个整数N,V分别表示物品数量和背包容积
接下来有N行,每行两个整数vi和wi分别表示第i件物品的体积和价值
输出一个整数表示最大价值
样例1:
4 5
1 2
2 4
3 4
4 5
输出样例:
8
样例2:
4 12
3 1
2 5
5 4
7 7
输出样例:
13

本人已经大二下,然而现在意识到学计算机不学算法等于不学。所以打算偶尔记录自己的学习过程。

首先创建一个二维列表dp,其中dp[i][j]表示:在容量为j的情况下,对于i个物品来说,所能装的最大价值。这就分为两种情况:

第一个是容量j小于物品的体积vi,这种情况下物品肯定装不进去,那么dp[i][j]的值就等于dp[i - 1][j] (由于第i个物品装不进去,那么对于这i个物品,所能装入背包的最大价值是装i - 1个物品的最大价值)

第二个是容量j大于等于物品i的体积vi,这时又分为两种情况:装或者不装。

①:不装的话那么那么dp[i][j]的值就等于dp[i - 1][j](由于第i个物品不装,那么对于这i个物品,所能装入背包的最大价值是装i - 1个物品的最大价值)

②:装的话那么装入物品i后的最大价值就是在容量为j的情况下不装物品i时的最大价值加上物品i的价值。即dp[i][j] = dp[i - 1][j - v[i]] + w[i]为什么要j - v[i]?因为在容量为j的情况下,我们已经选择要装入物品i了,那么在装入物品i之前的的背包容量就要减去物品i的体积了。我们必须要知道装入物品i之前,背包的最大价值,也就是dp[i - 1][j - v[i]]

然而第二种情况还没完:有没有一种可能?装了物品i之后的背包价值还没有不装物品i的高?所以需要把第二种情况的两个小情况进行比较,选取最大的那个结果,即

MAX = max(dp[i - 1][j],dp[i - 1][j - lst_v[i]] + lst_w[i])

也就是说要求装入i个物品的最大价值,就必须要知道装入i - 1个物品的最大价值,如此类推,那么只装入一个物品的最大价值是我们必须要知道的。所以必须要对二维数组初始化。

到此动态规划的思路就讲完了。下面讲讲如何使用python实现二维列表呢?我们可以新建一个一维列表,然后往其中加入多个新的一维列表。那么最开始的列表就是二维列表了。这个二维列表的行的个数就是其中一维列表的个数,列的个数就是每个一维列表的元素个数

综上:代码如下:

n,v = map(int,input().split())
lst_v = []#物品的体积
lst_w = []#物品的价值
dp = []#这就是初始化二维列表
temp = []#要向二维列表中加入的一维列表
for i in range(n):
    a,b = map(int,input().split())
    lst_v.append(a)
    lst_w.append(b)
for i in range(v + 1):#初始化二维列表的第一行
    if i < lst_v[0]:
        temp.append(0)
    else:
        temp.append(lst_w[0])
dp.append(temp)
#动态规划:
for i in range(1,n):#n个物品
    temp = []
    for j in range(v + 1):#背包容积从无到满
        if j < lst_v[i]:
            temp.append(dp[i - 1][j])
        else:
            MAX = max(dp[i - 1][j],dp[i - 1][j - lst_v[i]] + lst_w[i])
            temp.append(MAX)
    dp.append(temp)
last = []
for i in dp:
    print(i)
for i in dp:
    last.append(max(i))
print(max(last))

你可能感兴趣的:(动态规划,算法,python)