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 }

原题链接:https://www.lintcode.com/problem/92/

posted @ 2021-04-06 18:07  没有你哪有我  阅读(99)  评论(0编辑  收藏  举报