zoukankan      html  css  js  c++  java
  • LeetCode Backpack

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

    Example

    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.

    解题思路:

    一、申请一块辅助空间,dp[A.length][m+1],dp[i][j]的含义是当只有A[0..i]的物品,且背包容量为j的时候,背包最多能够装多少。

    辅助数组dp[i][j]的值的取值方案:(看不懂先看下面案例流程)

    1、          容量j < A[i],也就是说背包中不能装A[i]物品,于是dp[i][j] = dp[i-1][j];

    2、          容量j > A[i],现在背包中能够装下i物品,于是我们有两种选择方案:

    a)       装入A[i]物品,于是我装入i物品以后的背包的容量就只有j-A[i],于是剩下A[0…i-1]物品,以及j-A[i]的背包容量,于是dp[i][j]=A[i]+dp[i][j-A[i]];

    b)       另一种方案就是我能装A[i],但是我不装进去。

    于是dp[i][j] = max(dp[i][j], dp[i][j-A[i]] + A[i])

    二、上面的没有看懂没有关系,我们举个例子分析流程以后再回来看。

    1、假设A={2,3,4,5},背包size=10,首先申请dp空间,并且选择A[0]物品

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    2

    0

    0

    2

    2

    2

    2

    2

    2

    2

    2

    2

    3

    4

    5

    现在假设就只有物品A[0],size = 2,当背包容量j为0和1的时候,背包容量j < A[0],当背包容量 j > A[0],但是此时只有A[0]物品,所以最多只能装入A[0].

    2、假设现在能够选择A[0]和A[1]物品

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    2

    0

    0

    2

    2

    2

    2

    2

    2

    2

    2

    2

    3

    0

    0

    2

    3

    3

    5

    5

    5

    5

    5

    5

    4

    5

    当背包容量j为0、1、2的时候,不能j< [i] 所以dp[i][j] = dp[i-1][j],也就是不在背包中装入A[1]物品,那么现在背包中的只可能装入a[0],所以dp[1][j]的状态和dp[0][j]一样。当背包容量 j > A[1],于是dp[i][j]就有两种选择,装入A[1]个不装入A[1],然后选择两种情况下的最大值:dp[i][j] = max(dp[i][j], dp[i-A[i]] + A[i])

    3、          假设现在能够选择A[0]、A[1]、A[2]物品

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    2

    0

    0

    2

    2

    2

    2

    2

    2

    2

    2

    2

    3

    0

    0

    2

    3

    3

    5

    5

    5

    5

    5

    5

    4

    0

    0

    2

    3

    4

    5

    5

    5

    5

    9

    9

    5

    4、假设现在能够选择A[0]、A[1]、A[2]、A[3]物品

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    2

    0

    0

    2

    2

    2

    2

    2

    2

    2

    2

    2

    3

    0

    0

    2

    3

    3

    5

    5

    5

    5

    5

    5

    4

    0

    0

    2

    3

    4

    5

    6

    7

    7

    9

    9

    5

    0

    0

    2

    3

    4

    5

    6

    7

    8

    9

    10

    总之更具上面的dp[i][j]的值的决策方案走就能够得出最终结果。

    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) {
            if (m <= 0 || A == null || A.length == 0) {
                return 0;
            }
            int len = A.length;
            int[][] dp = new int[len][m + 1];
            for (int i = 0; i <= m; i++) {
                if (i >= A[0])
                    dp[0][i] = A[0];
            }
            for (int i = 1; i < len; i++) {
                for (int j = 0; j <= m; j++) {
                    if (j >= A[i]) {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - A[i]] + A[i]);
                    } else {
                        dp[i][j] = dp[i - 1][j];
                    }
                }
            }
            return dp[len - 1][m];
        }
        public static void main(String[] args) {
            int m = 10;
            int[] arr = {3, 4, 8, 5};
            int s = new Solution().backPack(m, arr);
            System.out.println(s);
        }
    }

    题目二

    Given n items with size Ai and value Vi, and a backpack with size m. What's the maximum value can you put into the backpack?

    Example

    Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.

    public class Solution {
        /**
         * @param m: An integer m denotes the size of a backpack
         * @param A & V: Given n items with size A[i] and value V[i]
         * @return: The maximum value
         */
       public int backPackII(int m, int[] A, int V[]) {
    
            if (m <= 0 || A == null || A.length == 0 || V == null || V.length == 0) {
                return 0;
            }
    
            int len = A.length;
            int[][] dp = new int[len][m + 1];
    
            for (int i = 0; i <= m; i++) {
                if (i >= A[0])
                    dp[0][i] = V[0];
            }
    
            for (int i = 1; i < len; i++) {
                for (int j = 0; j <= m; j++) {
                    if (j >= A[i]) {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - A[i]] + V[i]);
                    } else {
                        dp[i][j] = dp[i - 1][j];
                    }
                }
            }
    
            return dp[len - 1][m];
        }
    }

    题目三:给定数组arr,arr中所有的值都为正且不重复,每个整数可以使用无数次,给定一个正整数aim,从arr中选择一个任意数字组合,求和为aim的数字组合有多少种。

    Example:

    arr={5,10,25,1}, aim=0 

    组成0园的方式有一种,就是都不用

    arr={5,10,25,1},aim=15

    组成15有6种方式:3个5,1个5+1个10,一个10+5个1,1个5+10个1,2个5+5个1,一个15,返回6

    解题思路:申请辅助空间dp[i][j],dp[i][j]的值的含义为当只选择arr[0...i]的时候,有多少种方式可以组成j

    dp[i][j]的值的决策方案:

    1、当不选择arr[i],dp[i][j] = dp[i-1][j]

    2、当选择arr[i],如果 j <arr[i] 就无法选择arr[i],dp[i][j] = dp[i-1][j],当j>arr[i],且选择了arr[i],dp[i][j] = dp[i-1][j]+dp[i][j-arr[i]]

    public int backPackVI(int[] nums, int target) {
                int len = nums.length;
        
                int[][] dp = new int[len][target + 1];
        
                for (int i = 0; i < len; i++) {
                    dp[i][0] = 1;
                }
                for (int i = 1; nums[0] * i <= target; i++) {
        
                    dp[0][nums[0] * i] = 1;
                }
        
                for (int i = 1; i < len; i++) {
                    for (int j = 1; j <= target; j++) {
                        if (j >= nums[i])
                            dp[i][j] += dp[i - 1][j] + dp[i][j - nums[i]];
                        else
                            dp[i][j] = dp[i - 1][j];
                    }
                }
                return dp[len - 1][target];
            }

    该题可以进行空间压缩,参考代码如下:

    public int backPackVI2(int[] nums, int target) {
            // Write your code here
            int[] dp = new int[target + 1];
            dp[0] = 1;
    
            for (int i = 0; i < nums.length; ++i)
                for (int j = 0; j <= target; ++j)
                    if (j >= nums[i])
                        dp[j] += dp[j - nums[i]];
    
            return dp[target];
        }



  • 相关阅读:
    vue 中简单路由的实现
    Vue中对生命周期的理解
    内存泄漏
    前端工程化
    exports 和 module.exports 的区别
    Nodejs的url模块方法
    MongoDB 的获取和安装
    Anjular JS 的一些运用
    移动端vconsole调试
    安装fiddler时,电脑浏览器没网
  • 原文地址:https://www.cnblogs.com/googlemeoften/p/5836508.html
Copyright © 2011-2022 走看看