要用回溯算法解决问题需要将问题抽象为一个决策序列,一步步做决策,直到问题解决。如果发现某一步已经没有可以解决问题的决策了,或者决策序列已经到头但问题还未解决,就退回上一步进行其它的决策。
1.基本解决问题的思路
解决一个回溯问题,实际上就是一个决策树的遍历过程。需要关注的几个问题:
- 决策路径:也就是已经做出的决策序列,最终的决策序列就是问题的解。
- 选择列表:当前可以做的选择。
- 成功条件:完成任务的条件。
- 结束条件:一般是决策序列到头了或者已经确定必然无法完成任务了。
典型的回溯算法代码如下:
|
|
2.回溯VS枚举
穷举法,先要把一个问题的所有可能解都列举出来,再一一检查是否满足问题条件,丢弃不满足的的解,剩下符合条件的解。
回溯法,一个解的生成是逐步进行的,当途中发现该解已经不可能满足需求了,就会提前放弃这个解,避免接下来不必要的解生成计算。可以理解为剪枝,剪掉了提前发现的不必要的计算分支。
因此在实际使用中,回溯法会比枚举法有更优秀的性能表现。
3. 0-1背包问题
题目:一个背包的总容量是9个单位。几个物品的重量分别为 2,2,4,6,2。选择几样商品装进背包,使得装进背包的物品总重量最大。之所以称之为0-1背包,意思是这个物品要么选择整个放进背包,要么选择整个不放进背包,不能选择部分放入背包。
每次考察一件商品,选择为 放 or 不放。如果放入某件商品,会造成背包总量溢出,则直接可以选择不放。如果达到终止条件,则和当前记录的最大总量对比,选择更大的那个。
3.1 如果只要求出最大值,不要求找出选择的物品
|
|
3.2 如果同时要求找出任一个使得总重量最大的物品下标
|
|