LintCode刷题——背包问题(动态规划)
题目描述
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]
你不可以将物品进行切割。
样例
样例 1:
输入: [3,4,8,5], backpack size=10
输出: 9
样例 2:
输入: [2,3,5,7], backpack size=12
输出: 12
挑战
O(n x m) 的时间复杂度 and O(m) 空间复杂度
如果不知道如何优化空间,O(n x m) 的空间复杂度也可以通过.
优化空间思路——滚动数组
AC代码
1 public class Solution { 2 /** 3 * @param m: An integer m denotes the size of a backpack 4 * @param A: Given n items with size A[i] 5 * @return: The maximum size 6 */ 7 public int backPack(int m, int[] A) { 8 // write your code here 9 int n = A.length; 10 if (n == 0 || m == 0) { 11 return 0; 12 } 13 14 int[][] dp = new int[2][m + 1]; 15 16 dp[0][0] = 0; 17 for (int i = 1; i <= 1; i++) { 18 dp[i][0] = 0; 19 } 20 21 for (int i = 1; i <= m; i++) { 22 dp[0][i] = 0; 23 } 24 25 // 滚动数组 26 int old = 0; 27 int now = 1; 28 29 // time O(n * m) capacity O(n * m) 30 // first thing second capacity 31 // 这里注意:数组是只开两行,而外层循环还是要处理n次 32 for (int i = 1; i <= n; i++) { 33 // 循环完一行就滚动一下 34 old = now; 35 now = 1 - now; 36 for (int j = 1; j <= m; j++) { 37 // 选最大,设为无穷小 38 dp[now][j] = Integer.MIN_VALUE; 39 if (A[i - 1] > j) { 40 dp[now][j] = dp[old][j]; 41 } else { 42 dp[now][j] = Math.max(dp[old][j], dp[old][j - A[i - 1]] + A[i - 1]); 43 } 44 } 45 } 46 47 // 注意:此时的now就是最后一次计算之后的结果所存放的行 48 return dp[now][m]; 49 } 50 }