【Lintcode】125. Backpack II

题目地址:

http://www.lintcode.com/problem/backpack-ii/description

0-1背包问题, A A 表示物品体积, V V 表示物品价值。用动态规划。设 f [ i ] [ j ] f[i][j] 是前 i i 个物品里取出若干总重量不超过 j j 的物品的价值最大值。这个最大值有两种可能,要么包含物品 i i ,此时最大值是 f [ i 1 ] [ j A [ i ] ] + V [ i ] f[i-1][j-A[i]]+V[i] ;要么不包含物品 i i ,此时最大值是 f [ i 1 ] [ j ] f[i-1][j] 。比较一下这两个最大值取大者,就是 f [ i ] [ j ] f[i][j] 。从上面的式子看出,更新顺序是, i i 从小到大, j j 也是从小到大。代码如下:

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @param V: Given n items with value V[i]
     * @return: The maximum value
     */
    public int backPackII(int m, int[] A, int[] V) {
        // write your code here
        int[][] f = new int[A.length][m + 1];
        
        for (int i = 0; i <= m; i++) {
            f[0][i] = A[0] <= i ? V[0] : 0;
        }
    
        for (int i = 1; i < A.length; i++) {
            for (int j = 0; j <= m; j++) {
                f[i][j] = f[i - 1][j];
                if (j >= A[i]) {
                    f[i][j] = Math.max(f[i][j], f[i - 1][j - A[i]] + V[i]);
                }
            }
        }
        
        return f[A.length - 1][m];
    }
}

时空复杂度 O ( n m ) O(nm) n n 是物品数量。

接下来考虑优化空间复杂度。可以看到, f [ i ] [ j ] f[i][j] 的值只取决于上一行正上方元素和上一行左边的元素,所以可以按行滚动做空间优化。每一行需要从右向左更新,否则的话更新到 f [ i ] [ j ] f[i][j] 的时候, f [ i 1 ] [ j A [ i ] ] f[i-1][j-A[i]] 已经被覆盖掉了,这个时候答案已经得不到了。具体代码如下:

import java.util.Arrays;

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @param V: Given n items with value V[i]
     * @return: The maximum value
     */
    public int backPackII(int m, int[] A, int[] V) {
        // write your code here
        int[] f = new int[m + 1];
        
        for (int i = 1; i <= m; i++) {
            f[i] = A[0] <= i ? V[0] : 0;
        }
        
        // f[j] The max value of taking the first i items with total volume <= m
        for (int i = 1; i < A.length; i++) {
            for (int j = m; j >= 0; j--) {
                if (j >= A[i]) {
                    f[j] = Math.max(f[j], f[j - A[i]] + V[i]);
                }
            }
        }
        
        return f[m];
    }
}

时间复杂度不变,空间 O ( m ) O(m)

发布了113 篇原创文章 · 获赞 0 · 访问量 3318

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/104092237