背包问题解析(二)-递归算法
一、题目:
有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。
二、递归方法:
首先对于每个物品,我们的选择只有两个:放或者不放。我们将所有的可能都穷举出来,就可以得到下面这个树状图(只画了前四个结点):

所以对于每一个子问题,由于前面的子问题已被解决,因此我们都只需要做两个选择:放,还是不放。
假设我们已经知道了前i−1个物品放入背包的最优方案F(i−1,v i−1 ),那么对于第i个物品要放入背包就有三种情况:
1、若物品的体积c i 大于背包剩余的容量v i−1 ,那么只能丢弃这个物品:
F(i,vi)=F(i−1,vi−1)
2、否则就有两种选择:
(1)、不放第i个物品:
F(i,vi)=F(i−1,vi−1)
(2)、放第i个物品:
F(i,vi)=wi+F(i−1,vi−1−ci)
要从这两个方案中选择总价值最大的,所以:

三、python代码实现如下:
def rec_bag(c, w, v, i=0): """ param c: 物品体积 param w: 物品价值 param v: 当前背包剩余容量 param i: 当前物品编号 return: 背包装下物品的最大价值 """ if i > len(c) - 1: return 0 elif v <= 0: # 体积不能为负 return 0 elif v > 0: if c[i] <= v: A = w[i] + rec_bag(c, w, v - c[i], i + 1) B = rec_bag(c, w, v, i + 1) res = max(A, B) # 两种方案中选最优的那个并返回 else: res = rec_bag(c, w, v, i + 1) # 物品体积大于背包容量,直接返回 return res a = rec_bag([5,4,3,2], [6,5,4,3], 10, 0) print(a)
查看运行结果:
四、算法分析:
递归方法最大的缺点就在于有较多重复的计算,通过上面的树状图可以知道,递归会遍历这棵树的所有结点,所以它的时间复杂度为:O(2 n )
O(2n),指数阶的时间复杂度对于计算机来说简直就是灾难!
有没有什么办法减少这些重复的计算呢?这就是接下来要说的动态规划,它可以通过存储已经计算出来的结果来减少重叠子问题。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了