LintCode领扣 题解丨大厂经典动态规划:背包问题

简介: LintCode领扣 题解丨大厂经典动态规划:背包问题

在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]。

你不可以将物品进行切割。
在线评测地址:
https://www.lintcode.com/problem/backpack/?utm_source=sc-tianchi-sz0821

样例 1:

输入:  [3,4,8,5], backpack size=10
输出:  9

样例 2:

输入:  [2,3,5,7], backpack size=12
输出:  12

算法:DP

从已知的题目中,可以总结出以下两点:

每件物品只有一种
每件物品最多选择一次
那么考虑对于前i件的物品在容量为w的背包下,最大的装载量是多少,由此可以总结出对应的子结构,进行动态规划。

算法思路

设计dp数组dpn,用dpi表示第i个物品在容量为j的背包下,最大的装载量。

在这个问题中,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i−1件物品的问题:

如果不放第i件物品,可得dpi=dpi−1
如果放了第i件物品,可得dpi=dpi−1]+A[i] (j≥A[i])
总结状态转义方程为:dpi=max(dpi−1,dpi−1]+A[i])

复杂度分析

n表示物品件数,m表示背包容量

时间复杂度:O(nm)
空间复杂度:O(nm)
算法优化观察上方的状态转义方程,可以发现dpi方程的两个状态都只和dp[i-1]有关,显然通过O(nm)的空间复杂度,难免会浪费一些空间。

可以考虑使用滚动数组优化,建立dp数组dp[m],使用dp[j-A[i]]代替dpi-1]。优化后状态转义方程为dp[j]=max(dp[j],dp[j−A[i]]+A[i])

优化后复杂度分析

时间复杂度:O(nm)

空间复杂度:O(m)

代码思路分析

建立数组dp[m]表示背包容量为m的情况下,最大的装载量
初始化dp[0]=0
正序枚举A[i],并倒叙枚举j,这样所需要的dp[j-A[i]]不会被提前更新
最后返回dp[m],表示背包容量在m下的答案
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) {
    // write your code here
    // 如果背包容量或者物品数量为0,则直接返回
    if (A.length == 0 || m == 0) {
        return 0;
    }
    int n = A.length;
    int[] dp = new int[m + 1];
    for (int i = 0; i < n; i++) {
        // 滚动数组优化 倒序枚举j
        for (int j = m; j >= A[i]; j--) {
            dp[j] = Integer.max(dp[j], dp[j - A[i]] + A[i]);
        }
    }
    return dp[m];
}

}
更多大厂面试动态规划题解参见九章算法官网:
https://www.jiuzhang.com/course/76/?utm_source=sc-tianchi-sz0821

相关文章
|
5月前
|
存储 算法 搜索推荐
力扣每日一题 6/13 反悔贪心算法
力扣每日一题 6/13 反悔贪心算法
44 1
|
5月前
|
缓存
力扣每日一题 6/14 动态规划+数组
力扣每日一题 6/14 动态规划+数组
37 1
|
5月前
|
存储 算法
力扣经典150题第三十五题:螺旋矩阵
力扣经典150题第三十五题:螺旋矩阵
18 0
|
5月前
|
算法 索引
力扣每日一题 6/28 动态规划/数组
力扣每日一题 6/28 动态规划/数组
51 0
[算法刷题题解笔记] 洛谷 P1007 独木桥 [贪心]
[算法刷题题解笔记] 洛谷 P1007 独木桥 [贪心]
蓝桥杯备赛leetcode 70.爬楼梯,用最经典的题目来讲解动态规划
题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼梯顶部呢?
蓝桥杯备赛leetcode 70.爬楼梯,用最经典的题目来讲解动态规划
|
移动开发
力扣264周赛题解
力扣264周赛题解
89 0
【力扣刷题】整数拆分(动态规划)
动态规划其基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解,经分解得到子问题往往不是互相独立的,举个简单的例子:你知道两个1相加等于2,问你三个1相加你是拿前面的两个1相加的结果加上1呢,还是再用1+1+1,你肯定会用前面的那种方法对吧,这就是动态规划,(1+1)就是(1+1+1)的子问题,且并不是相互独立,你得到了(1+1)就好得到(1+1+1)了
158 0
【力扣刷题】整数拆分(动态规划)
力扣288周赛题解
第一题: 分析: 这道题呢,就是让你交换奇偶性相同的两个数字,让最后的值变成最大,解题 的方式有很多, 第一种能想到的就是一个数字一个数字的交换(同奇同偶),再进行比较,但是这种方法的可行性不高并且非常繁琐,稍有不注意就会少一种情况。 第二种方式就是开两个数组,通过求余数的方式,把奇数偶数分别放到不同的数组,把两个数组进行排序,再次遍历原来的数,判断每一位是技术还是偶数,从而从不同的数组中取出相应的大值,进行输出。 第三种就是利用双指针,所谓的双指针就是两层循环,外(i)层从开头开始遍历,内(j)层从末
82 0
力扣288周赛题解