码迷,mamicode.com
首页 > 其他好文 > 详细

Backpack II

时间:2016-06-27 23:06:20      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

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

标签:

原文地址:http://www.cnblogs.com/sherylwang/p/5621773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!