Python算法题解:动态规划解0-1背包问题

简介: Python算法题解:动态规划解0-1背包问题

概述

背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。

定义

我们有 n 种物品,物品 j 的重量为wj,价格为pj。
我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。

如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。

如果限定物品j最多只能选择bj个,则问题称为有界背包问题。

如果不限定每种物品的数量,则问题称为无界背包问题。

动态规划

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。

通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。

思路

举例,令物品数量N=5,背包所能承受的最大重量为W=10,物品与价格的对应关系如下表左三列所示。

screenshot

当放入物品a时,在背包所能承受的重量内,计算背包拥有的物品总价格,并进行标记,如表格第一行所示,当背包所能承受的重量大于等于2时,都可以放入物品a,背包拥有的物品总价格为6。

接着我们放入物品b,放入之前,一是要判断背包是否所能承受其重量,二是判断放入之后与放入之前拥有的物品总价格哪个最大,如表格第二行所示,当背包所能承受的重量大于等于2时,都可以放入物品b,但是,物品b在背包容量为[2,3]的时候,放入之后的总价格3不如放入之前的总价格6大,所以不放入。

当背包所能承受的重量等于4时,放入物品b后,背包所能承受的重量4减去物品b的重量2后,剩余的所能承受的重量2还可以放入物品a,此时背包拥有的物品总价格为物品a和物品b的总价格之和,即为9,大于放入之前的物品总价格6,所以此时背包拥有的物品总价格最大为9。

分析可知,在一层循环遍历下,我们需要一个一维数组保存背包所能承受的最大重量与其拥有的物品总价格,并不断更新。

代码

Copy/0-1背包问题@paramN物品数量@paramW背包容量@paramweight物品重量@paramvalue物品价格@return最大价值/privatestaticinttraceBack(intN,intW,int[]weight,int[]value){int[]dp=newint[W+1];//范围[0,W]当前背包容量对应的物品总价值for(inti=0;i=weight[i];j--){//只要背包可以放入就放dp[j]=Math.max(dp[j-weight[i]]+value[i],dp[j]);//比较放入物品之前与放入之后的价值哪个大}}returndp[W];}
复杂度

显而易见,算法需要的时间复杂度为O(nW),空间的消耗(即所需的一维数组)为O(W)。

有不清楚的地方,伙伴们可以留言,更多的Python相关教程也会继续为大家更新!

相关文章
|
3月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
2月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
65 2
|
3月前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
118 2
动态规划算法学习三:0-1背包问题
|
3月前
|
存储 算法 Python
【10月更文挑战第16天】「Mac上学Python 27」小学奥数篇13 - 动态规划入门
本篇将通过 Python 和 Cangjie 双语介绍动态规划的基本概念,并解决一个经典问题:斐波那契数列。学生将学习如何使用动态规划优化递归计算,并掌握编程中的重要算法思想。
113 3
|
3月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
85 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
3月前
|
算法
动态规划算法学习二:最长公共子序列
这篇文章介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题,包括问题描述、最优子结构性质、状态表示、状态递归方程、计算最优值的方法,以及具体的代码实现。
194 0
动态规划算法学习二:最长公共子序列
|
3月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
194 0
|
3月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
10天前
|
机器学习/深度学习 算法
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
145 80
|
4天前
|
机器学习/深度学习 算法
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。