DFS 是最基础的搜索算法,但它的变化和应用非常丰富。
一、DFS 本质
DFS = 深度优先搜索 = 一条路走到黑,碰壁再回头。
void dfs(int u) {
if (到达目标状态) { 处理答案; return; }
for (每个可能的下一步 v) {
if (v 合法且未访问) {
标记 v 已访问;
dfs(v);
取消标记(回溯);
}
}
}
二、DFS 的三大应用场景
- 图/树的遍历:最基础的应用,前序/中序/后序遍历
- 回溯算法:八皇后、全排列、子集枚举、组合
- 记忆化搜索:用数组存储已计算状态,避免重复计算
三、剪枝技巧(非常重要!)
- 可行性剪枝:当前分支不可能到达解,直接返回
- 最优性剪枝:当前分支不会比已有最优解更好,直接返回
- 顺序剪枝:改变搜索顺序,优先搜索更可能成功的分支
- 对称性剪枝:利用对称性减少搜索空间
四、迭代加深搜索(IDDFS)
当搜索深度未知且可能很深时使用:
- 设定深度限制 depth
- 如果未找到解,逐步增加深度限制
- 结合 A 启发式函数 → IDA 算法
五、DFS 序
DFS 遍历过程中给节点标号,子树对应连续区间,可将树上问题转化为序列问题。
六、双向搜索(Meet in the Middle)
将问题分成两半,分别 DFS 搜索,然后合并结果。复杂度从 O(2^n) 降至 O(2^(n/2))。
推荐练习:
- 八皇后:经典回溯
- 洛谷 P1706 全排列问题
- 洛谷 P1219 八皇后(加强版)
- 洛谷 P1120 小木棍(经典 IDDFS + 剪枝)
暂无评论,快来抢沙发吧~ 🛋️