0/1背包问题--回溯法--c++,c语言(二)

本文通过回溯法解决0/1背包问题,详细介绍了解题思路和扩展规则。以深度优先搜索解空间树,并利用剪枝函数提高效率。提供了一个包含4个物品的案例,分析了时间复杂度为O(n)。通过代码演示和解释,确保覆盖所有可能情况,包括背包未装满但价值最优的情况。

0/1背包问题

本篇是用回溯法求解0/1背包问题,结合上篇回溯法求解的步骤(忘了的小伙伴可以再看下),我们来对这个问题进行分析,

解决思路:

(1)确定问题的解题空间树:从n个集合中求取最优解,很显然其解空间是子集树(每个物品要么装入,要么不装入)。每个结点表示背包的一种选择状态。

(2)确定结点的扩展规则:对于本问题的解空间树,用i表示层数,第i层上的某分枝结点的对应状态dfs(i,tw,tv,rw,op),tw当前背包中物品重量,tv当前背包中物品价值,rw(剪枝函数时用到)考虑第i个物品时剩余物品的重量,op解向量。拓展可能有两种:

(1)选择第i个物品放入背包,tw=tw+w[i],tv=tv+v[i],(这里先不讲rw的用法,可以先不管),op[i]=1,接着转向下一个状态dfs(i+1,tw,tv,rw,op),这是左分枝。

(2)不选择第i个物品,op[i]=0,tw=tw,tv=tv,转向下一个状态dfs(i+1,tw,tv,rw,op),这是右分枝。

例:对于层次为1的根结点为(0,0),考虑物品1(这里的数据我下面会给出,这里大家就当成参考数据来看)

(1)选择物品1:op[1]=1,tw=0+5=5,tv=0+4=4,产生新的结点(5,4)作为根的左孩子。

(2)不选择物品1:op[1]=0,tw=0,tv=0,产生新的结点(0,0),作为根的右孩子。

 

w[]数组是存放物品的重量,v[]数组是存放物品的价值,W背包容量

(3)以深度优先方式搜索解空间树,并采用剪枝函数避免无效搜索,提高效率:对于左枝点(物品都放包内)可能会出现tw+w[i]>W的情况,所以这些完全可以删去,所以满足tw+w[i]<=W,的结点才可以继续往纵深走。对于右枝点(物品不放包内),我们添加一个参数rw(考虑i

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值