1、概述
回溯法
是一种搜索法(穷举法),被称为通用的解题方法,本质是树的前中后序遍历,具体情况具体分析。这种方法适用于解一些组合数相当大的问题。通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量)。
深度优先搜索(DFS)是一种用于遍历或搜索树或图的算法,本质是树的前序遍历。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
2、回溯和深度优先搜索的区别
回溯是一种更通用的算法。可以用于任何类型的结构,无论它是否是逻辑树(隐式树)还是显式树。
深度优先搜索是显式树或图结构相关的特定形式的回溯法。目的是遍历,不一定要通过回溯才能得到结果。
- 回溯处理隐式树、显式树。可以是树的前中后序遍历
- DFS 处理显式树,并且偏向于遍历穷举。大多数是树的先序遍历。
3、回溯法模版
3.1 回溯法的基本思想
- 针对所给问题,定义问题的解空间;
- 确定易于搜索的解空间结构;
- 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
3.2 代码模版
4、DFS模版(深度优先搜索)
深度优先搜索基本模型
void dfs(int step) {
//判断边界
//尝试每一种可能
for (int i=1;i<=n;i++){
//记录一些数据,例如
sun++
//继续下一步
dfs(step+1);
}
//返回
}
经典的DFS例题:啊哈算法的解救小哈和炸弹人(图的深度优先搜索)
//核心代码
void dfs(int x, int y, int step) {
int next[ 4][2]={
{
0, 1
},//向右走
{
1, 0
},//向下走
{
0, -1
},//向左走
{
-1, 0
}
} ;//向上走
int tx, ty, k;
//判断是否到达小哈位置
if (x == p && y == q) {
if (step < min)
min = step;
return;
}
//枚举四种走法
for (k = 0; k <= 3; k++) {
//计算下一个点的坐标
tx = x + next[k][0];
ty = y + next[k][1];
//判断是否越界
if (tx < 1 || tx > n || ty < 1 || ty > m)
continue;
//判断该点是否有障碍物或者已经在路径上
if (a[tx][ty] == 0 && book[tx][ty] == 0) {
book[tx][ty] = 1;//标记这个点已经走过
dfs(tx, ty, step + 1);//尝试下一个点
book[tx][ty] = 0;//尝试结束,取消标记,恢复现场
}
}
return;
}
5、代码区别
子集树:x[t]=i;//记录痕迹,记录 t标记的每一层,试探每一层的所有可能
DFS图的遍历:dfs(tx, ty, step + 1);//从当前节点向下扩展,逐个试探