Backpack II
Posted Sheryl Wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Backpack II相关的知识,希望对你有一定的参考价值。
Given n items with size Ai and value Vi, and a backpack with size m. What‘s the maximum value can you put into the backpack?
Given 4 items with size [2, 3, 5, 7]
and value [1, 5, 2, 4]
, and a backpack with size 10
. The maximum value is 9
.
这是最经典的0-1背包问题。即有n件物品,每个物品有体积Ai, 价值Vi。然后有一个容量为m的背包,要求可以放入背包的最大价值。特点是每件物品只有一件,可以选择放或者不放。
定义状态,背包问题的经典定义,f[i,j]表示前i个物品当中选一些物品组成容量为j的最大价值。转换状态为对于第i 个物体取不取做一个选择。
即f[i,j] = max(f[i-1,j],f[i-1,j-A[i]]+V[i])前者为不取第i 个物体,后者为取第i 个物体。
初始化,注意这题不要求一定装满背包,所以初始化是f[0][j] =0, 如果要求装满,则f[0][0] = 0, f[0][j] = -∞。(来自背包九讲)。
最终结果为f[n,m]。
注意在每次转换时,j的取值,如果取第i 个物体,则背包的大小必须大于Ai,否则无法做状态转换。所以在j小于A[i]时,直接取f[i-1,j]。
注意这题可以采用滚动数组做优化,毕竟每次都是对i做一个变换。对于j小于A[i]的情况,使用滚动数组也有优势,即完全不需要考虑j小于A[i]的情况,只需要直接继承就可以。非优化代码如下:
class Solution: # @param m: An integer m denotes the size of a backpack # @param A & V: Given n items with size A[i] and value V[i] # @return: The maximum value def backPackII(self, m, A, V): n = len(A) dp = [[0] * (m+1) for i in xrange(n+1)] for i in xrange(1,n+1): for j in xrange(0, m+1): dp[i][j] = dp[i-1][j] if j >= A[i-1]: dp[i][j] = max(dp[i-1][j],dp[i-1][j-A[i-1]]+V[i-1]) return dp[n][m]
优化代码如下:
class Solution: # @param m: An integer m denotes the size of a backpack # @param A & V: Given n items with size A[i] and value V[i] # @return: The maximum value def backPackII(self, m, A, V): n = len(A) dp = [0] * (m+1) for i in xrange(0,n): for j in xrange(m, A[i]-1, -1): dp[j] = max(dp[j],dp[j-A[i]]+V[i]) return dp[m]
可以看到非优化代码不仅浪费空间,在时间复杂度上也很浪费。必须做j的一个判断。所以以后默认使用滚动数组做优化。
以上是关于Backpack II的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Backpack - 内联创建,未在数据库中添加关系
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段
设置中的 Laravel-Backpack/Settings 表字段