动态规划背包问题详解(二)---0-1背包问题

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

/**
 * 对于技术面试,你还在死记硬背么?
 * 快来“播”沙糖橘吧,
 * 用视频案例为你实战解读技术难点
 * 聚焦Java技术疑难点,实战视频为你答疑解惑
 * 越“播”越甜的沙糖橘,期待你的到来和参与
 * 更多详情,
 * 请关注公众号沙糖橘:shatangju8801
 * 请留意QQ交流群:798470346
 */
--------------------------------------------------------------------------------------------------------------------------------

2.1 题目描述

最基本的背包问题就是0-1背包问题(0-1 knapsack problem):

问题描述:

给定n种物品和一固定容量m的背包。物品i的体积【或者重量】是wi,其价值为vi,背包的容量为W。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

在0-1背包问题中,对于一种物品,要么装入背包,要么不装。

对于一种物品的装入状态可以取0和1,设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-1背包问题。

2.2 解题思路分析

如果采用暴力穷举的方式,每件物品都存在装入和不装入两种情况,所以总的时间复杂度是O(2^N),这是不可接受的。而使用动态规划可以将复杂度降至O(NW)。我们的目标是背包内物品的总价值,而变量是物品和背包的限重,所以定义结果状态数组dp:

dp[i][j] 表示将前i件物品装进容量为j的背包可以获得的最大价值, 0<=i<=N, 0<=j<=W
补充:j表示在选择“装入”物品i时背包可用的容量

那么可以将动态规划的状态结果数组dp[i][j]的第一列:dp[0][0...W]初始化为0,表示将前0个物品(即没有物品)装入容量为0...W的背包中依次对应的最大价值为0。那么当 i > 0 时,dp[i][j]有两种情况:

(1) 不装入第i件物品,即当前背包容量为j的情况下,背包中最大价值为:dp[i−1][j]

(2) 装入第i件物品(前提是能装下),当前背包价值为:dp[i−1][j−w[i]] + v[i]

在装入物品i之后,背包的价值不一定时最大价值,此时需要和不装入物品i时的背包的价值作比较,选择二者中的max作为当前的背包的最大价值,所有需要使用状态转移方程确认最大价值,状态转移方程为:

dp[i][j] = max(dp[i−1][j], dp[i−1][j−w[i]]+v[i]) // j >= w[i]

下面解析一下这个状态转换方程,这个方程非常重要,是所有动态规划背包问题的基础,其他的相关背包问题都是在次基础上衍生出来的。

详细解读一下状态转换方程:

“将前 i 件物品放入容量为 j 的背包中”这个子问题,若只考虑第 i 件物品的策略(放或不放),那么就可以转化为一个只牵扯前 i−1 件物品的问题:

如果不放第 i 件物品,那么问题就转化为“前 i−1 件物品放入容量为 j 的背包中”,价值为 dp[i−1][j]

如果放入第 i 件物品,那么问题就转化为“前 i−1 件物品放入剩下的容量为 j−w[i]的背包中”,其中 w[i] 是第 i 件物品所占用的背包的容量,此时能获得的最大价值就是 dp[i−1][j−w[i]],再加上通过放入第 i 件物品获得的价值 v[i]。

该算法的时间和空间复杂度均为O(m*n),其中时间复杂度已经不能再优化了,但空间复杂度却可以优化到 O(n),后面会介绍0-1背包的空间优化算法。

由上述状态转移方程可知,dp[i][j]的值只与dp[i-1][0,...,j-1]有关,所以我们可以采用多重循环完成动态规划算法,伪代码如下:

// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 01背包问题伪代码(二维数组未优化版)
dp[0][0,...,W] = 0
for i = 1,...,N // N个物品可选 N=w.length
    for j = 1,...,w // 遍历每一个背包可用容量下的最优解
    //for j = W,...,min(w) // 注意,此处j循环的右边界值为数组w中的最小元素的值,或者直接取值为1
                         // 另外,j的循环可以从max-->min   也可以从 min-->max 二者等价
        // 装不下
        if w[i]>j
            dp[i][j] = dp[i−1][j]
        else // 装的下
            dp[i][j] = max(dp[i−1][j], dp[i−1][j−w[i]]+v[i])
​

编程实现代码如下:

    /**
     * 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
     * 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
     * 动态规划算法——空间优化算法
     *
     * @param m 总容量
     * @param w 物品体积数组
     * @param v 物品价值数组
     * @return 动态规划的结果数组
     */
private static int[][] test(int m, int[] w, int[] v) {
        // 动态规划数组,为了方便动态规划条件从1开始,数组维数+1
        int[][] dp = new int[w.length][m + 1];        
        // 初始化
        for (int i = 0; i < w.length; i++) {
            for (int j = 1; j < m + 1; j++) {
                dp[i][j] = 0;
            }
        }
        // 获取放入背包物品中,体积最小的物品的体积值        
        // 填充动态规划数组
        // 变量物品个数,尝试每个物品进行规划处理
        for (int i = 1; i < w.length; i++) {
            // 背包容量的遍历规划
            for (int j = 1; j < m + 1; j++) { // 下标可以从1--m+1 进行遍历,可以正向枚举遍历,也可以逆向枚举遍历
                //当背包里的物品为i件重量为j时,如果第i件的重量为weight【i-1】小于重量j时,dp【i】【j】有下列两种情况
                //(1)物品i不放入背包,所以dp[i][j]为dp[i-1][j]的值
                //(2)物品i放入背包,则背包剩余重量为j-weight[i-1],所以从dp[i][j]为dp[i-1][j-weight[i-1]]的值加上当前物品i的值
                if (w[i] > j) { // (1)
                    dp[i][j] = dp[i - 1][j];
                } else { // (2)
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
                }
            }
        }
        return dp;
    }

空间和价值数组w和v的预处理:

注意在算法理论描述中,本算法为了i的下标都从1开始处理物品,需要对数组w和v进行预处理,预处理方法如下,在调用本方法之前需要自行对数组w和v进行预处理:

// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 改造w和v数组,是i和数组小标从1开始,下标为0的元素填充0
        // 例如:[2,3,4] ---> [0,2,3,4]
        int[] w = new int[w0.length+1];
        System.arraycopy(w0,0, w, 1, w0.length);
        int[] v = new int[v0.length+1];
        System.arraycopy(v0,0, v, 1, v0.length);

对于第二层for循环遍历下标的问题说明:

// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 获取放入背包物品中,体积最小的物品的体积值
        int wMin = getMinVal(w);
        // 填充动态规划数组
        // 变量物品个数,尝试每个物品进行规划处理
        for (int i = 1; i < w.length; i++) {
            // 背包容量的遍历规划
            for (int j = m; j > wMin; j--) { // 注意此处,见代码后面的说明:【循环下标说明】
                //当背包里的物品为i件重量为j时,如果第i件的重量为weight【i-1】小于重量j时,dp【i】【j】有下列两种情况
                //(1)物品i不放入背包,所以dp[i][j]为dp[i-1][j]的值
                //(2)物品i放入背包,则背包剩余重量为j-weight[i-1],所以从dp[i][j]为dp[i-1][j-weight[i-1]]的值加上当前物品i的值
                if (j < w[i]) { // (1)
                    dp[i][j] = dp[i - 1][j];
                } else { //(2)
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
                }
            }
        }
​

【循环下标说明】

此处的下标可以从最大的容量m开始倒序遍历,但是遍历终止边界值不是 w[i],而是数组w中的最小值,或者直接设置终止边界值为1;具体为什么请课下自行思考说明。

在使用二维数组dp进行0-1背包算法实现时,背包的可用容量 j 变量在for循环中可以正序遍历也可以逆序遍历,计算结果是一样的。


0-1背包空间优化算法

对前面的采用二维状态转换数组的算法进行如下分析:

采用二维状态转换数组的算法中的主循环 i=1...N,每次算出来二维数组 dp[i][0...W]的所有值。那么,如果只用一个数组dp[0...W],能不能保证第 i 次循环结束后dp[j]中表示的就是之前定义的状态dp[i][j]呢?dp[i][j]是由dp[i-1][j]dp[i−1][j−w[i]]两个子问题域递推而来,能否保证在推导dp[i][j]时(也即在第 i 次主循环中推导dp[j]时)能够得到dp[i-1][j]dp[i−1][j−w[i]]的值呢?事实上,这要求在每次主循环中以j=W...0的顺序推dp[j],这样才能保证推导dp[j]dp[j−w[i]]保存的是状态dp[i-1][j-w[i]]的值。

经过前面分析发现,由上述状态转移方程可知,dp[i][j]的值只与dp[i-1][0,...,j-1]有关,所以可以采用动态规划常用的方法(滚动数组)对空间进行优化(即去掉dp的第一维)。需要注意的是,为了防止上一层循环的dp[0,...,j-1]被覆盖,循环的时候 j 只能逆向枚举(空间优化前没有这个限制,可以正向也可以逆向),伪代码为:

// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 01背包问题伪代码(空间优化版)
dp[0,...,W] = 0
for i = 1,...,N // N个物品可选 N=w.length
    for j = W,...,w[i] // 必须逆向枚举,否则无法实现最优解;逆向枚举之前的值相当于是上一次物品选取的最优解,
                       //在此基础上进行本次的最优解的选取;注意,必须逆向遍历。
        dp[j] = max(dp[j], dp[j−w[i]]+v[i]) // dp[j] 等价于未放入物品i时的最大值;dp[j−w[i]]+v[i]等价于放入物品i时的最大值

结合上面的伪代码可以分析空间优化算法的缘由:

空间优化算法中的dp[j]=max(dp[j],dp[j−w[i]])恰好就等价于转移方程dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]),因为现在的dp[j−w[i]]就相当于原来的dp[i−1][j−w[i]]。如果将W的循环顺序从上面的逆序改成顺序的话,那么则成了dp[i][j]dp[i][j−w[i]]推知,与本题意不符,但它却是另一个重要的背包问题(完全背包)最简捷的解决方案,所以熟练掌握一维数组解0-1背包问题是非常必要和重要的。

空间优化算法的时间复杂度为O(NW), 空间复杂度为O(W),相对于二维数组的算法,时间负责度没有在优化的余地,对空间复杂度进行了优化。由于W的值是W的位数的幂,所以这个时间复杂度是伪多项式时间。

动态规划的核心思想避免重复计算在0-1背包问题中体现得淋漓尽致。第 i 件物品装入或者不装入而获得的最大价值完全可以由前面 i-1 件物品的最大价值决定,这样可以保证每次获取的都是最优解。

具体实现代码如下:

    /**
     * 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
     * 动态规划算法——空间优化算法
     *
     * @param m 总容量
     * @param w 物品体积数组
     * @param v 物品价值数组
     * @return 动态规划的结果数组
     */
    private static int[] test(int m, int[] w, int[] v) {
        // 动态规划数组,为了方便动态规划条件从1开始,数组维数+1
        int[] dp = new int[m + 1];
        // 初始化
        for (int i = 0; i < m + 1; i++) {
            dp[i] = 0;
        }
        // 获取放入背包物品中,体积最小的物品的体积值        
        // 填充动态规划数组
        // 变量物品个数,尝试每个物品进行规划处理
        for (int i = 1; i < w.length; i++) {
            // 背包容量的遍历规划
            for (int j = m; j >= w[i]; j--) { // 必须逆向枚举遍历!!!  注意此处,见代码后面的说明:【循环下标说明】
                //当背包里的物品为i件重量为j时,如果第i件的重量为weight【i-1】小于重量j时,dp【i】【j】有下列两种情况
                //(1)物品i不放入背包,所以dp[i][j]为dp[i-1][j]的值
                //(2)物品i放入背包,则背包剩余重量为j-weight[i-1],所以从dp[i][j]为dp[i-1][j-weight[i-1]]的值加上当前物品i的值
                dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);
            }            
        }
        return dp;
    }
​

【循环下标说明】

此处的下标必须最大的容量m开始倒序遍历,且遍历终止边界值是 w[i];具体为什么请课下自行思考说明。

另外注意,此算法依然需要对数组w和v进行预处理,预处理方式见上文:空间和价值数组w和v的预处理

补充:此处下标只能逆向枚举遍历,不能正向枚举遍历。

因为:逆向枚举遍历是0-1背包动态规划算法;

正向枚举遍历是完全背包动态规划算法;

2.3 循环因子的优化【数据量较大时优势】

上面的空间优化算法代码中的内层循环 :

......
// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 变量物品个数,尝试每个物品进行规划处理
        for (int i = 1; i < w.length; i++) {
            // 背包容量的遍历规划
            // 此处循环因子 j 的边界值可以进行优化
            for (int j = m; j >= w[i]; j--) { // 必须逆向枚举遍历!!!  注意此处,见代码后面的说明:【循环下标说明】
                //当背包里的物品为i件重量为j时,如果第i件的重量为weight【i-1】小于重量j时,dp【i】【j】有下列两种情况
                //(1)物品i不放入背包,所以dp[i][j]为dp[i-1][j]的值
                //(2)物品i放入背包,则背包剩余重量为j-weight[i-1],所以从dp[i][j]为dp[i-1][j-weight[i-1]]的值加上当前物品i的值
                dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);
            }            
        }
 ......       

对于for (int j = m; j >= w[i]; j--)来说,可以将这个循环因子的下限进行改进。由于只需要求解最后dp[j]的值,而求解dp[j]的值需要倒推前一个物品,其实只要知道 dp[j−w[n]]即可。以此类推,对于空用容量为 j 的背包,其实只需要求得 dp[j−sum(w[i...n])]即可,上面的空间优化算法的代码可以优化为:

......
// 公众号沙糖橘:shatangju8801,请留意QQ交流群:798470346,沙糖橘社区倾心锻造~_~
// 变量物品个数,尝试每个物品进行规划处理
        for (int i = 1; i < w.length; i++) {
            // 背包容量的遍历规划
            // 此处循环因子 j 的边界值可以进行优化
            // 循环因子 j 下限值
            int bound = max(w[i],m - sum{w[i + 1]...w[n]}) // m 是背包的总容量
            // 上式等价于
            int bound = max(w[i], m - (s[n] - s[i])); // m 是背包的总容量,s[n] - s[i] 表示 w 数组中 i+1 到n的和
            for (int j = m; j >= w[i]; j--) { // 必须逆向枚举遍历!!!  注意此处,见代码后面的说明:【循环下标说明】
                //当背包里的物品为i件重量为j时,如果第i件的重量为weight【i-1】小于重量j时,dp【i】【j】有下列两种情况
                //(1)物品i不放入背包,所以dp[i][j]为dp[i-1][j]的值
                //(2)物品i放入背包,则背包剩余重量为j-weight[i-1],所以从dp[i][j]为dp[i-1][j-weight[i-1]]的值加上当前物品i的值
                dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);
            }            
        }
 ......       

对于求 sum 可以用前缀和,这对于 V 比较大时是有用的。这种优化处理对于处理大数据量时,可以提升算法的性能。

对于0-1背包问题的总结:

0-1背包问题是最基本的背包问题,它包含了背包问题中如何设计状态转换方程的最基本思想,其他的类型的背包问题往往也可以转换成0-1背包问题求解。仔细体会0-1背包问题的基本思路,状态转移方程的意义,以及最后怎样优化的空间复杂度。这是学习所有背包问题的基础和出发点

算法设计与分析 0-1背包问题 动态规划解法【超详细】 0-1背包问题 问题描述 给定i个物品和一个容量为的背包,物品的重量是Wi,其价值为Vi 物品个数为i,背包容量为C。 如何选择装入背包内的物品,使得装入背包中的物品的总价值最大? 其中,每种物品只有全部装入背包或不装入背包两种选择。 物品不能分割,不能重复使用。 动态规划算法思路 首先建立一个数组B[i][c],最上面一行表示背包容量,最左边一列表示物品编号,中间填充的数值表示当当前背包容量为C... 阅读详情

相关推荐

动态规划0-1背包问题详解+分析+原码)

本篇文章将介绍算法专题之动态规划中的背包问题,更准确的说是背包问题中最简单的一种类型,即0-1背包问题,就是给你一定容量的背包和若干物品,每种物品只能选一次,告诉你每件物品的价值和体积,求背包里面物品的最大总价值。

未见花闻的博客 4万+

动态规划背包问题

注意:for j in range(1,m+1):是枚举所有的情况,不用一一判断放入物品后背包容量减少后j的变化。为什么从1开始,因为0已经写出来了,即dp[i-1][j]=dp[i-1][j-0*a[i-1]]+0*v[i-1]。 01背包无价值 n=len(a) dp=[[False]*(m+1) for i in range(n+1)] dp[0][0]=True for i in range(1,n+1): dp[i][0]=True for j in range(1,m+1)

he_Microsoft的博客 1184

动态规划0-1背包问题

关于背包问题,其实可以分为两种类型:0-1背包问题 和 部分背包问题1、先通过一个例子来说明一下者的区别吧! 有一个窃贼在偷窃一家商店时发现有n件物品,第i件物品价值为vi元,重量为wi,假设vi和wi都为整数。他希望带走的东西越值钱越好,但他的背包中之多只能装下W磅的东西,W为一整数。他应该带走哪几样东西? 0-1背包问题:每件物品或被带走,或被留下,(需要做出0-1选择)。小偷

小邓笔记 3万+

动态规划-背包问题

算法背包问题动态规划

qq_52147470的博客 3087

九种 0-1 背包问题详解

目录 动态规划概念 问题10-1背包问题 问题2:完全背包问题 问题3:多重背包问题 问题4:混合背包问题 问题5:背包问题 问题6:分组背包问题 问题7:有依赖的背包问题(困难) 问题8:背包问题求方案数 问题9:背包问题求具体方案 前言 0-1 背包是一个经典的问题,之前也整理过一篇关于 0-1 背包的博客,当时只是整理了 0-1 背包问题的4 种解决方法。最近在复习算法,发现有很多 0-1 背包问题的衍生问题。0-1 背包问题的限制条件既可以是重量,也可以是容量,或者..

Tyler_Zx的博客 2万+

彻底搞懂0-1背包问题动态规划

看了很多网上的博客,发现对于0-1背包问题很多讲的都很专业,初学者学起来还是比较吃力,今天我就用最简单最形象的语言来描述一下0-1背包问题,为什么不能用贪婪算法,而要选择使用动态规划。 首先对于0-1背包问题,我们需要知道的是:每一个物品只有1个,要么全拿,要么不拿,最后使得拿到的物品的总价值最大。 假如一个小偷有一个可以容纳4千克的背包,但是发现面前只有有3样物品可以偷:台灯(30元,4千克)、音响(20元,3千克)、充电宝(15元,1千克)(价格和重量可能有点奇怪????)。问,小偷能够偷到的物品的

HarryXu的博客 2万+

动态规划】(动态规划——0-1背包问题

整理总结动态规划中的01背包理论基础,对比总结一维和维数组的定义、初始化及其遍历顺序,引入01背包的应用场景,包括能否装满背包、背包最多能装多少、装满背包有几张方法,装满背包最多有多少个物品等。

weixin_46216674的博客 1万+

算法——动态规划0-1背包问题

打算每天复习一点算法内容,就先从动态规划下手。曾经动态规划让我头疼,重新学了一下觉得还好啦不是很难,实现动态规划算法的核心在于实现它的递推公式,写出递推公式,代码也就很容易了。动态规划类似分治法,都是将一个大问题分解为一个个小问题,分而治之。不同之处在于,动态规划记忆了重复的子问题,避免了运算过程中的重复计算。适用情况:有重叠子问题和最优子结构性质(动态规划每一步求的都是最优解)的问题。下面我们通...

Astar的博客 1万+

动态规划-0-1背包问题

下面我用容积代表重量(我是不会承认我看走眼了的。又懒得改。)0-1背包问题动态规划背包问题系列的最基础的一个问题。相对理解起来较为简单。按书上来说,要证明一个问题是否可以使用动态规划思想,需要满足最优子结构的性质,那么什么是最优子结构的性质呢?书上给出的定义如下图看起来很拗口,其实就是不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。说白了就是一个最优策略的子策略也是必须是最优的,而所有子问题的局部最优解将导致整个问题的全局最优。

菜鸟的博客 1万+

动态规划法解决0/1背包问题详解

强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan 是什么 动态规划(dynamic programming)是求解决策过程最优化的数学方法,把多阶段过程转换为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法。 基本思想 将待求解的问题分解成若干个子问题,先求解子问...

至尊宝 3万+

动态规划解决0-1背包问题详解(图文并茂)

动态规划解决0-1背包问题 这个是网上比较好的案例,因为原文有些地方晦涩难懂,对于刚接触动态规划问题的朋友来说很不友好,所以很对地方加入了我自己的见解,也是作为我的一次学习历程。 一、问题描述: 有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 、总体思路: 根据动态规划解题步骤(问题抽象化、建立模型、寻找约束条件、判断是否满足最优性原理、找大...

BigData_Mining的博客 1万+

动态规划算法背包问题——0/1背包问题,多目标优化背包问题详解与示例

背包问题动态规划中的一个经典问题,通常有两种主要变种:0/1 背包问题背包问题(Fractional Knapsack Problem)。这里我们先详细解释0/1背包问题再介绍背包问题的变种。

qq_35831906的博客 1万+

动态规划0-1背包问题

动态规划0-1背包问题 动态规划0-1背包问题是一个十分典型案例,我从网上查询好多相关资料,但是大部分都深奥难懂,并不适合初学算法的小白,其中涉及的递推关系式、填表,以及最后的维表简化为一维表的优化过程,好多都是一笔带过,所以,今天就尽我所能,来叙述一下对于0-1背包问题使用动态规划来求解。 要解决0-1背包问题,首先咱们要解决的是什么是动态规划动态规划 先说一说什么是动态规划动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题

weixin_49571787的博客 6419

动态规划之经典案例《0-1背包问题详解

0-1背包问题描述 有一个可装重量为w的背包和n件物品,每件物品都有重量和价值两个属性,且每件物品只有一件,只能选择装入或者不装,能装入的最大物品价值是多少? 一、贪心算法分析 看到求最值问题,一般是使用动态规划来解。为什么不使用贪心算法来解?因为贪心算法求的是局部最优解,而动态规划才能求得全局最优解。 举个例子: 现在有以下物品重量和价值数组W、V,背包最多装入9kg物品。 W = [4,6,5,2] V = [7,8,5,3] 使用贪心算法时,每一步要做的就是对于第i件物品,我取还是不取,且只能抉择

mbytes的博客 4391

0-1背包问题动态规划

动态规划的核心思想就是把一个大问题分解成很多小问题,然后逐个解决这些小问题,最后把这些小问题的解组合起来,就得到了大问题的解。为什么要用动态规划?有些问题直接解决很难,但是分解成小问题就容易多了。很多小问题是重复的,我们可以把这些小问题的解保存起来,避免重复计算。背包问题,就像在玩一个非常有趣的“装箱”游戏!想象一下,你有一个背包,它只能装下一定重量的东西。现在,你面前有一堆玩具,每个玩具都有自己的重量和价值,每个玩具只能装一个。在背包的重量限制下,装下尽可能多的玩具,并且让这些玩具的总价值最高。

m0_74062928的博客 2688

动态规划0/1背包问题原理详解: 简明、细致、深入理解

动态规划0/1背包问题,回溯

yw906002599的博客 1万+

动态规划法求解0/1背包问题

一、求解0/1背包问题 1、问题描述 有n个重量分别为{w1,w2,…,wn}的物品,它们的价值分别为{v1,v2,…,vn},给定一个容量为C的背包。 设计从这些物品中选取一部分物品放入该背包的方案,每个物品要么选中要么不选中,要求选中的物品的总重量不能超过背包的容量,求具有最大的价值的装载方案。 2、蛮力法求解 3、证明0/1背包问题满足最优性原理 4、问题分析 (1)第1步 问题结构分...

wmy01234的博客 1万+

动态规划0-1背包问题。(算法设计与分析详解

背包问题通俗的说,就是假如你面前有5块金块速分别为a, b, c, d, e,每块金块的重量不同,并且每块金块所带来的价值也不同(注意:这里金块的重量的价值没有特定关系),目前我们有一个背包,只有固定的容量,要解决的问题就是在一定容量的背包面前装哪几块金块才能获取到最大的价值,对于每块金块我们只有拿或者不拿这两种选择,拿为1不拿为0,因此叫做0-1背包问题。下面我们给出思想,以及步骤。

q805370101的博客 5783
上一篇: 动态规划背包问题详解(一)---动态规划基本概念
shatangju8801
博客等级 码龄19年 12粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值