算法题之动态规划-01背包问题

简介: 详细讲解算法题之动态规划-01背包问题

文章首发于我的个人博客,到个人博客体验更佳阅读哦

https://www.itqiankun.com/article/1564909352

文字介绍解决背包问题

假设山洞里共有a,b,c,d ,e这5件宝物(不是5种宝物),它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包, 怎么装背包,可以才能带走最多的财富。

此时只要理解了状态转换方程f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] },就知道这道算法的答案了,这个状态转换方程是怎么来的呢?往下看

假如背包要放第i件物品,此时如果不放第i件物品,那么问题就转化为“前i-1件物品放入重量是w的背包中”,价值为f[i-1,j];
如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的重量为j-Wi的背包中”,此时能获得的最大价值就是f[i-1,j-Wi]
再加上通过放入第i件物品获得的价值Pi,此时只要比较f[i-1,j]和f[i-1,j-Wi]+Pi那个大就能获取到背包里最大的价值是多少了。

可能还是不是太懂,那么我们看图来理解,这里就使用大佬的图片了,就是下面的图片,有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,怎么获取价值最大的背包呢

20190724183559279

首先对这个图片要知道的是:

  • 明确这张表是至底向上,从左到右生成的。
  • 然后用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。
  • 对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。
  • 同理,c2=0,b2=3,a2=6。

对于承重为8的背包,a8=15,是怎么得出的呢?根据01背包的状态转换方程,需要考察两个值,就是下面的两个

  • 一个是f[i-1,j],这种情况就是承重为8的背包里面不放a这个物品这一种情况(根据上面的状态转换方程来的),这里i就是下面的横列的值,然后j就是指竖列的值,所以此时f[i-1,j]里面的i就是a、j就是8,因为a的下一列是b,所以f[i-1,j]就是指b8,所以此时的f[i-1,j]的值就是9
  • 另一个是f[i-1,j-Wi]+Pi,这种情况就是承重为8的背包里面要放a这个物品这一种情况(根据上面的状态转换方程来的),既然要放a这个物品,那么此时的Pi的值就是6(因为a商品的价值是6),然后因为承重为8的背包里面已经确定要放a这个物品,所以此时这个背包里面最多还只能存放的重量就是6,这里i就是下面的横列的值,然后j就是指竖列的值,所以此时f[i-1,j-Wi]里面的i就是a、j就是8、Wi就是2(这个2就是a物品的重量),所以此时f[i-1,j-Wi]就是指b6,此时b6的值是9,所以f[i-1,j-Wi]+Pi=9+6=15,所以物品a应该放入称重是8的背包里面

java代码解答这个背包问题

下面的红色代码注释里面的数组里面的第一个索引都是0,这是为了避免数组的0索引问题

下面的蓝色代码注释里面的for循环目的就是为了创建 这样的一个图片20190724183559279
,然后只要创建好上面的图片,那么我们就能知道背包问题的答案了

package com.one.util;

public class Test {
    public static int getMaxValue(int[] weight, int[] value, int w, int n) {
        int[][] table = new int[n + 1][w + 1];// 创建一个二维数组,横列是物品的价值,竖列是物品的重量
        // 蓝色代码注释开始
        for (int i = 1; i <= n; i++) { //物品
            for (int j = 1; j <= w; j++) {  //背包大小
                if (weight[i] > j) {
                    //当前物品i的重量比背包容量j大,装不下,肯定就是不装
                    table[i][j] = table[i - 1][j];
                } else { //装得下,Max{装物品i, 不装物品i}
                    table[i][j] = Math.max(table[i - 1][j], table[i - 1][j - weight[i]] + value[i]);
                }
            }
        }
        // 蓝色代码注释结束
        return table[n][w];
    }

    public static void main(String[] args) {
        int n = 5, w = 10;                    //物品个数,背包容量
        // 红色代码注释开始
        int[] value = {0,6, 3, 5, 4, 6};     //各个物品的价值
        int[] weight = {0,2, 2, 6, 5, 4};    //各个物品的重量
        // 红色代码注释结束
        System.out.println(getMaxValue(weight, value, w, n));
    }
}

原文链接

大佬链接
https://www.itqiankun.com/article/1564909352

目录
相关文章
|
7天前
|
存储 算法 Java
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
21 4
算法系列之动态规划
|
15天前
|
算法 安全 调度
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
|
15天前
|
机器学习/深度学习 算法 测试技术
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
|
2月前
|
算法 Java C++
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
58 5
|
4月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
91 2
|
5月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
108 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
11天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
83 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
|
2天前
|
机器学习/深度学习 数据采集 算法
基于PSO粒子群优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-LSTM-SAM网络时间序列预测算法。使用Matlab2022a开发,完整代码含中文注释及操作视频。算法结合卷积层提取局部特征、LSTM处理长期依赖、自注意力机制捕捉全局特征,通过粒子群优化提升预测精度。适用于金融市场、气象预报等领域,提供高效准确的预测结果。
|
2天前
|
算法 数据安全/隐私保护
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。
|
3天前
|
算法 数据挖掘 数据安全/隐私保护
基于CS模型和CV模型的多目标协同滤波跟踪算法matlab仿真
本项目基于CS模型和CV模型的多目标协同滤波跟踪算法,旨在提高复杂场景下多个移动目标的跟踪精度和鲁棒性。通过融合目标间的关系和数据关联性,优化跟踪结果。程序在MATLAB2022A上运行,展示了真实轨迹与滤波轨迹的对比、位置及速度误差均值和均方误差等关键指标。核心代码包括对目标轨迹、速度及误差的详细绘图分析,验证了算法的有效性。该算法结合CS模型的初步聚类和CV模型的投票机制,增强了目标状态估计的准确性,尤其适用于遮挡、重叠和快速运动等复杂场景。

热门文章

最新文章