LintCode刷题——背包问题 III(动态规划)
题目描述
给定 n
种物品, 每种物品都有无限个. 第 i
个物品的体积为 A[i]
, 价值为 V[i]
.
再给定一个容量为 m
的背包. 问可以装入背包的最大价值是多少?
- 不能将一个物品分成小块.
- 放入背包的物品的总大小不能超过
m
.
样例
样例 1:
输入: A = [2, 3, 5, 7], V = [1, 5, 2, 4], m = 10
输出: 15
解释: 装入三个物品 1 (A[1] = 3, V[1] = 5), 总价值 15.
样例 2:
输入: A = [1, 2, 3], V = [1, 2, 3], m = 5
输出: 5
解释: 策略不唯一. 比如, 装入五个物品 0 (A[0] = 1, V[0] = 1).
标签
背包型动态规划 动态规划
AC代码
1 public class Solution { 2 /** 3 * @param A: an integer array 4 * @param V: an integer array 5 * @param m: An integer 6 * @return: an array 7 */ 8 public int backPackIII(int[] A, int[] V, int m) { 9 // write your code here 10 int n = A.length; 11 if (m == 0 || n == 0) { 12 return 0; 13 } 14 15 int[][] dp = new int[2][m + 1]; 16 17 dp[0][0] = 0; 18 19 for (int i = 1; i <= 1; i++) { 20 dp[i][0] = 0; 21 } 22 23 for (int i = 1; i <= m; i++) { 24 dp[0][i] = 0; 25 } 26 27 // 滚动数组,减少空间复杂度 28 // 此时的空间复杂度为:O(m) 29 int old = 0; 30 int now = 1; 31 for (int i = 1; i <= n; i++) { 32 old = now; 33 now = 1 - now; 34 for (int j = 1; j <= m; j++) { 35 if (A[i - 1] > j) { 36 dp[now][j] = dp[old][j]; 37 } else { 38 // 枚举可以放几个第i件物品,这里k一定要从开始,为的是后面选出最大价值时要跟dp[i - 1][j]比,如果这里不比的话,结果可能会有偏差 39 for (int k = 0; k * A[i - 1] <= j; k++) { 40 // 这里注意:第i件物品可能不止放一件,所以这里是要跟dp[i][j],即跟自身比,跟放k - 1件时的自己比 41 dp[now][j] = Math.max(dp[now][j], dp[old][j - k * A[i - 1]] + k * V[i - 1]); 42 } 43 } 44 } 45 } 46 47 return dp[now][m]; 48 } 49 }