题目描述 小明有一个容量为 V的背包。 这天他去商场购物,商场一共有 N件物品,第 i件物品的体积为 wi,价值为 vi。 小明想知道在购买的物品总体积不超过 V的情况下所能获得的最大价值为多少, 请你帮他算算。 输入描述 输入第 1行包含两个正整数 N,V,表示商场物品的数量和小明的背包容量。 第2-N+1行包含2个正整数 w,v,表示物品的体积和价值。 1<=N<=10^2,1<=V<=10^3,1<=wi,vi<=10^3。 输出描述 输出一行整数表示小明所能获得的最大价值。 输入输出样例 示例 1 输入 5 20 1 6 2 5 3 8 5 15 3 3 输出 37 运行限制 最大运行时间:1s 最大运行内存: 128M
笔记:
DP状态设计:
DP状态:定义二维数组dp[][],大小为N*C。
dp[i][j]:将前i个物品(从第1个到第i个)装入容量为j的背包中获得的最大价值。
解题思路:
把每个dp[i][j]看成一个背包:背包容量为j,装1-i这些物品。
从dp[0][0]递推到dp[N][C]
dp[N][C]是问题的答案:把N个物品装进容量为C大的背包的最大价值。
DP转移方程:
(1)第i个物品的体积比容量j大,装不下去。
直接继承i-1个物品装进容量j的背包的情况即可;
dp[i][j]=dp[i-1][j]
(2)第i个物品的体积比容量j小,可以装进背包。
装第i个:第i个物品装进背包后,背包容量减少c[i],价值增加w[i]:
dp[i][j]=dp[i-1][j-c[i]]+w[i]
不装第i个:dp[i][j]=dp[i-1][j]
取最大值,状态转移方程:
dp[i][j]=max(dp[i-1][j],dp[i][j]=dp[i-1][j-c[i]]+w[i])
eg有四个物品,体积分别为{2,3,6,5},价值分别为{6,3,5,4},背包容量为9
dp[][]表:
包装容量:a \ b 0 1 2 3 4 5 6 7 8 9
不装:0
装前一个:1
装前二个:2
装前三个:3
装前四个:4
->dp[a][b]
步骤一:只装第一个物品
c1=2, a \ b 0 1 2 3 4 5 6 7 8 9
w1=6 0 0 0 0 0 0 0 0 0 0 0
1 0 0 6 6 6 6 6 6 6 6
物品1的体积2,所以背包容量小于2的,放不进去,得dp[1][0]=dp[1][1]=0;
物品1的体积等于背包容量,能装进去,背包价值等于物品1的价值,
dp[1][2] = 6;
容量大于2的背包,多余的容量用不到,所以价值容量2的背包一样
步骤2:只装前2个物品。
如果物品2体积比背包容量大,那么不能装物品2,情况和只装第1个一样
dp[2][0] = dp[2][1] = 0,dp[2][2] = 6。
dp[2][3]?物品2体积等于背包容量,那么可以装物品2,也可以不装:
(a) 如果装物品2(体积是3,价值也是3),那么可以变成一个更小的问题
即只把物品1装到(容量j-3)的背包中。
dp[2][3]=3+0(3(目前最大容量(j)-装入物品体积(3))=3
(b) 如果不装物品2,那么相当于只把物品1装到背包中取(a)和(b)的最大值,
得dp[2][3] = max3,6) = 6(直接继承)
∴ 不装更好一些
后续步骤: 继续以上过程,最后得到下图(图中的箭头是几个例子)最后的答案是
dp[4][9]: 把4个物品装到容量为9的背包,最大价值是11。
包装容量:a \ b 0 1 2 3 4 5 6 7 8 9
不装:0 0 0 0 0 0 0 0 0 0 0
c1=2,w1=6:1 0 0 6 6 6 6 6 6 6 6
c2=3,w2=3:2 0 0 6 6 6 9 9 9 9 9
c3=6,w4=5:3 0 0 6 6 6 9 9 9 11 11
c4=5,w4=4:4 0 0 6 6 6 9 9 10 11 11
复杂度:n*c
N, V = map(int, input().split())
dp = [0]*(V+1)
for _ in range(N):
w, v = map(int, input().split())
for j in reversed(range(w,V+1)):
dp[j] = max(dp[j], dp[j-w]+v)
print(dp[-1])
2436

被折叠的 条评论
为什么被折叠?



