题目链接
有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小和数组 V 表示每个物品的价值. 问最多能装入背包的总价值是多大?
上面的算法在计算第i行元素时,只用到第i-1行的元素,所以二维的空间可以优化为一维空间,但是如果是一维向量,需要从后向前计算,因为后面的元素更新需要依靠前面的元素未更新(模拟二维矩阵的上一行的值)的值
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 num = A.length; if(m == 0 || num == 0) return 0; //多加一列,用于设置初始条件,因为第一件商品要用到前面的初始值 int[] maxValue = new int[m + 1]; //初始化所有位置为0,第一行都为0,初始条件 for(int i = 0; i <= m; ++i){ maxValue[i] = 0; } for(int i = 1; i <= num; ++i){ for(int j = m; j > 0; --j){ //如果第i个商品大于j,说明放不下, 所以(i,j)的最大价值和(i-1,j)相同 //如果可以装下,分两种情况,装或者不装 //如果不装,则即为(i-1, j) //如果装,需要腾出放第i个物品大小的空间: j - A[i],装入之后的最大价值即为(i - 1, j - A[i-1]) + 第i个商品的价值V[i] //最后在装与不装中选出最大的价值 if(A[i - 1] <= j){ int newValue = maxValue[j - A[i - 1]] + V[i - 1]; maxValue[j] = Math.max(newValue, maxValue[j]); } } } //返回装入前N个商品,物品大小为m的最大价值 return maxValue[m]; } }