Skip to content

Latest commit

 

History

History
122 lines (104 loc) · 3.24 KB

File metadata and controls

122 lines (104 loc) · 3.24 KB

##Backpack

19% Accepted

Given n items with size Ai, an integer m denotes the size of a backpack.
How full you can fill this backpack?

If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5],
so that the max size we can fill this backpack is 10. If the backpack size is 12.
we can select [2, 3, 7] so that we can fulfill the backpack.

You function should return the max size we can fill in the given backpack.

####Note You can not divide any item into small pieces.

####Challenge

  • O(n x m) time and O(m) memory.
  • O(n x m) memory is also acceptable if you do not know how to optimize memory.

####Tags Expand

  • LintCode Copyright
  • Dynamic Programming
  • Backpack

####基本做法

  • Space O(m*n) 因为每次就在用f[i] f[i-1] 所以应该空间是可以优化的
  • Time O(m*n)
  • 参考 背包九讲
  • f[i][j] = Math.max(f[i-1][j-A[i-1]] + V[i-1], f[i-1][j])
public class Solution {

    public int backPack(int m, int[] A) {
        // write your code here
        if (m ==0 || A == null || A.length == 0) {
            return 0;
        }
        int[][] f = new int[A.length+1][m+1];
        for (int i = 0; i <= m; i++) {
            f[0][i] = 0;
        }
        for (int i = 1; i <= A.length; i++) {
            for (int j = 0; j <= m; j++) {
                if (j >= A[i-1]) {
                    f[i][j] = Math.max(f[i-1][j-A[i-1]] + A[i-1], f[i-1][j]);
                } else {
                    f[i][j] = f[i-1][j];
                }
            }
        }
        return f[A.length][m];
    }
}

####空间优化做法

  • 优化f[i][j]到f[j]
  • 此时第二重循环不能从j=0开始了,要从j=m开始 j--
  • 如果是j=0 j++开始,那么f[j-A[i-1]]用的就是新的值,不是原来的f[i-1][j-A[i-1]]而是刚计算完的f[1] f[2]这样
public class Solution {

    public int backPack(int m, int[] A) {
        // write your code here
        if (m ==0 || A == null || A.length == 0) {
            return 0;
        }
        int[] f = new int[m+1];
        f[0] = 0;
        for (int i = 1; i <= A.length; i++) {
            for (int j = m; j >= 0; j--) {
                if (j >= A[i-1]) {
                    f[j] = Math.max(f[j-A[i-1]] + A[i-1], f[j]);
                }
            }
        }
        return f[m];
    }
}

####或者这样更好理解

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @return: The maximum size
     */
    public int backPack(int m, int[] A) {
        // write your code here
        if (m <= 0 || A == null) {
            return 0;
        }

        int n = A.length;
        int[][] result = new int[2][m+1];
        for (int i = 0; i <= m; i++) {
            result[0][i] = 0;
        }
        for (int i = 0; i <= 1; i++) {
            result[i][0] = 0;
        }

        for (int i = 1; i <= n; i++) {
            for (int j = m; j >= 0; j--) {
                if (j - A[i-1] >= 0) {
                    result[i%2][j] = Math.max(result[(i-1)%2][j], result[(i-1)%2][j-A[i-1]] + A[i-1]);
                } else {
                    result[i%2][j] = result[(i-1)%2][j];
                }
            }
        }

        return result[A.length%2][m];
    }
}