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[j-A[i]];

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

于是dp[i][j] = max(dp[i][j], dp[i-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];
    }
}
时间: 2024-11-06 19:23:38

LeetCode Backpack的相关文章

[LeetCode] 416. Partition Equal Subset Sum_Medium tag: backpack

Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Note: Each of the array element will not exceed 100. The array size will not exce

九章算法 基础算法 强化算法 系统设计 大数据 安卓 leetcode 高清视频

leetcode 直播视频讲座录像 九章算法视频录像,PPT 算法班,算法强化班,Java入门与基础算法班,big data项目实战班,Andriod项目实战班 九章算法下载 九章算法面试 九章算法leetcode 九章算法答案 九章算法mitbbs 九章算法班 九章算法ppt 九章算法录像 九章算法培训 九章算法微博 leetcode 视频 九章算法偷录 算法培训 算法班课程大纲: 1 从strStr谈面试技巧与Coding Style(免费试听) 2 二分搜索与旋转排序数组 Binary S

[LintCode] Backpack VI 背包之六

Given an integer array nums with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target. Notice The different sequences are counted as different combinations. Have you met this questi

[LeetCode] 349 Intersection of Two Arrays &amp; 350 Intersection of Two Arrays II

这两道题都是求两个数组之间的重复元素,因此把它们放在一起. 原题地址: 349 Intersection of Two Arrays :https://leetcode.com/problems/intersection-of-two-arrays/description/ 350 Intersection of Two Arrays II:https://leetcode.com/problems/intersection-of-two-arrays-ii/description/ 题目&解法

LeetCode 442. Find All Duplicates in an Array (在数组中找到所有的重复项)

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? Example: Input: [4,3,2,7,

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

LeetCode OJ - Longest Consecutive Sequence

这道题中要求时间复杂度为O(n),首先我们可以知道的是,如果先对数组排序再计算其最长连续序列的时间复杂度是O(nlogn),所以不能用排序的方法.我一开始想是不是应该用动态规划来解,发现其并不符合动态规划的特征.最后采用类似于LRU_Cache中出现的数据结构(集快速查询和顺序遍历两大优点于一身)来解决问题.具体来说其数据结构是HashMap<Integer,LNode>,key是数组中的元素,所有连续的元素可以通过LNode的next指针相连起来. 总体思路是,顺序遍历输入的数组元素,对每个

LeetCode OJ - Surrounded Regions

我觉得这道题和传统的用动规或者贪心等算法的题目不同.按照题目的意思,就是将被'X'围绕的'O'区域找出来,然后覆盖成'X'. 那问题就变成两个子问题: 1. 找到'O'区域,可能有多个区域,每个区域'O'都是相连的: 2. 判断'O'区域是否是被'X'包围. 我采用树的宽度遍历的方法,找到每一个'O'区域,并为每个区域设置一个value值,为0或者1,1表示是被'X'包围,0则表示不是.是否被'X'包围就是看'O'区域的边界是否是在2D数组的边界上. 下面是具体的AC代码: class Boar

LeetCode 10. Regular Expression Matching

https://leetcode.com/problems/regular-expression-matching/description/ Implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover