算法系列--动态规划--背包问题(1)--01背包介绍(下)

简介: 算法系列--动态规划--背包问题(1)--01背包介绍(下)

算法系列--动态规划--背包问题(1)--01背包介绍(上)

https://developer.aliyun.com/article/1480834?spm=a2c6h.13148508.setting.14.5f4e4f0eIqvzeb

💕"趁着年轻,做一些比较cool的事情"💕

作者:Lvzi

文章主要内容:算法系列–动态规划–背包问题(1)–01背包介绍

大家好,今天为大家带来的是算法系列--动态规划--背包问题(1)--01背包介绍

状态转移方程

这里多了个限制条件dp[i - 1][j - v[i]] != -1,还是根据题目要求得来的,要考虑一种特殊情况,也就是在[0,i]区间内的物品根本无法组合成体积为j的情况(这也是会存在的),要想i位置存在价值,必须保证i-1位置刚好能够实现j-v[i]的体积

初始化相较于第一问也有所不同,具体来说需要把dp表的第一行初始化为-1(除了dp[0][0]),第一行代表不选择任何物品,也就无法构成满足j体积这个条件,我们将其设置为-1

之所以设置为-1是为了和dp[0][0] = 0这种情况作区分

代码:

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static int N = 1010;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), V = in.nextInt();// 获取物品数目和背包体积
        // 处理第一问
        int[] v = new int[N],w = new int[N];// 存储物品的体积和价值
        for(int i = 1; i <= n; i++) {// 输入数值
            v[i] = in.nextInt(); 
            w[i] = in.nextInt();
        }
        int[][] dp = new int[N][N];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= V; j++) {
                dp[i][j] = dp[i - 1][j];
                if(j - v[i] >= 0) 
                    dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - v[i]] + w[i]);
            }
        }
        System.out.println(dp[n][V]);
        // 处理第二问
        dp = new int[N][N];
        for(int j = 1; j <= V; j++) {// 初始化
            dp[0][j] = -1;
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= V; j++) {
                dp[i][j] = dp[i - 1][j];
                if(j - v[i] >= 0 && dp[i - 1][j - v[i]] != -1)
                    dp[i][j] = Math.max(dp[i - 1][j],dp[i - 1][j - v[i]] + w[i]);
            }
        }
        System.out.println(dp[n][V] == -1 ? 0 : dp[n][V]);
    }
}

上述解法的空间复杂度是很高的,我们开辟的dp表是一个N*N的,下面介绍使用滚动数组实现空间优化

空间优化之后的代码:

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static int N = 1010;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), V = in.nextInt();// 获取物品数目和背包体积
        // 处理第一问
        int[] v = new int[N],w = new int[N];// 存储物品的体积和价值
        for(int i = 1; i <= n; i++) {// 输入数值
            v[i] = in.nextInt(); 
            w[i] = in.nextInt();
        }
        int[] dp = new int[N];
        for(int i = 1; i <= n; i++) 
            for(int j = V; j >= v[i]; j--) 
                dp[j] = Math.max(dp[j],dp[j - v[i]] + w[i]);
            
        System.out.println(dp[V]);
        // 处理第二问
        dp = new int[N];
        for(int j = 1; j <= V; j++) 
            dp[j] = -1;// 初始化
        for(int i = 1; i <= n; i++) 
            for(int j = V; j >= v[i]; j--) 
                if(j - v[i] >= 0 && dp[j - v[i]] != -1)
                    dp[j] = Math.max(dp[j],dp[j - v[i]] + w[i]);
              
        System.out.println(dp[V] == -1 ? 0 : dp[V]);
    }
}

总结:本文的核心要点

  1. 什么是背包问题
  2. 01背包问题详解
  3. 背包问题的空间优化(滚动数组)

以上就是算法系列--动态规划--背包问题(1)--01背包介绍全部内容,下一篇文章将会带来01背包问题的拓展题目,敬请期待,我是LvZi


目录
相关文章
|
3月前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
62 8
|
2月前
|
机器学习/深度学习 算法 Java
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
|
2月前
|
算法 Java 测试技术
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法
这篇文章介绍了基于动态规划法的三种算法:解决背包问题的递归和自底向上实现、Warshall算法和Floyd算法,并提供了它们的伪代码、Java源代码实现以及时间效率分析。
算法设计(动态规划实验报告) 基于动态规划的背包问题、Warshall算法和Floyd算法
|
3月前
|
算法 Python
Python算法高手进阶指南:分治法、贪心算法、动态规划,掌握它们,算法难题迎刃而解!
【7月更文挑战第10天】探索Python算法的精华:分治法(如归并排序)、贪心策略(如找零钱问题)和动态规划(解复杂问题)。通过示例代码揭示它们如何优化问题解决,提升编程技能。掌握这些策略,攀登技术巅峰。
72 2
|
3月前
|
算法 程序员 Python
算法小白到大神的蜕变之路:Python分治法、贪心、动态规划,一步步带你走向算法巅峰!
【7月更文挑战第9天】探索算法之旅,以Python解锁编程高手之路。分治法如二分查找,将复杂问题拆解;贪心算法解决活动选择,每次选取局部最优;动态规划求斐波那契数列,避免重复计算,实现全局最优。每一步学习,都是编程能力的升华,助你应对复杂挑战,迈向算法大师!
37 1
|
1天前
|
传感器 算法 C语言
基于无线传感器网络的节点分簇算法matlab仿真
该程序对传感器网络进行分簇,考虑节点能量状态、拓扑位置及孤立节点等因素。相较于LEACH算法,本程序评估网络持续时间、节点死亡趋势及能量消耗。使用MATLAB 2022a版本运行,展示了节点能量管理优化及网络生命周期延长的效果。通过簇头管理和数据融合,实现了能量高效和网络可扩展性。
|
28天前
|
算法 BI Serverless
基于鱼群算法的散热片形状优化matlab仿真
本研究利用浴盆曲线模拟空隙外形,并通过鱼群算法(FSA)优化浴盆曲线参数,以获得最佳孔隙度值及对应的R值。FSA通过模拟鱼群的聚群、避障和觅食行为,实现高效全局搜索。具体步骤包括初始化鱼群、计算适应度值、更新位置及判断终止条件。最终确定散热片的最佳形状参数。仿真结果显示该方法能显著提高优化效率。相关代码使用MATLAB 2022a实现。
|
28天前
|
算法 数据可视化
基于SSA奇异谱分析算法的时间序列趋势线提取matlab仿真
奇异谱分析(SSA)是一种基于奇异值分解(SVD)和轨迹矩阵的非线性、非参数时间序列分析方法,适用于提取趋势、周期性和噪声成分。本项目使用MATLAB 2022a版本实现从强干扰序列中提取趋势线,并通过可视化展示了原时间序列与提取的趋势分量。代码实现了滑动窗口下的奇异值分解和分组重构,适用于非线性和非平稳时间序列分析。此方法在气候变化、金融市场和生物医学信号处理等领域有广泛应用。
|
29天前
|
资源调度 算法
基于迭代扩展卡尔曼滤波算法的倒立摆控制系统matlab仿真
本课题研究基于迭代扩展卡尔曼滤波算法的倒立摆控制系统,并对比UKF、EKF、迭代UKF和迭代EKF的控制效果。倒立摆作为典型的非线性系统,适用于评估不同滤波方法的性能。UKF采用无迹变换逼近非线性函数,避免了EKF中的截断误差;EKF则通过泰勒级数展开近似非线性函数;迭代EKF和迭代UKF通过多次迭代提高状态估计精度。系统使用MATLAB 2022a进行仿真和分析,结果显示UKF和迭代UKF在非线性强的系统中表现更佳,但计算复杂度较高;EKF和迭代EKF则更适合维数较高或计算受限的场景。
|
1月前
|
算法
基于SIR模型的疫情发展趋势预测算法matlab仿真
该程序基于SIR模型预测疫情发展趋势,通过MATLAB 2022a版实现病例增长拟合分析,比较疫情防控力度。使用SIR微分方程模型拟合疫情发展过程,优化参数并求解微分方程组以预测易感者(S)、感染者(I)和移除者(R)的数量变化。![]该模型将总人群分为S、I、R三部分,通过解析或数值求解微分方程组预测疫情趋势。
下一篇
无影云桌面