搜索
深度优先搜索
关于深搜的一些复习
首先明确什么是深搜。
深搜,即为深度优先搜索。
思想为:为了求得问题的解,先选择一种情况进行,如果情况可行,则继续向下寻找。若不可行,则返回上一层,选择另一种情况,再进行寻找,如此反复,直到得出答案或无解。
基本框架
int DFS (int n) { if ( n 满足条件 ) { 答案++ 或 保存结果 } else 不满足 for (int i = 1; i <= 限制条件; i++) { if ( 满足题意 或 满足继续搜索的条件 且 当前情况未访问) { 把当前情况设置为已访问 DFS ( 下一种情况 ) (恢复) 把当前情况设置为未访问 (回溯) } } }
例题 : n皇后问题
大意: 在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
思路:直接按照上面的伪代码来写从第一行第一列开始放,放完后将这一列,及两条对角线同时全部标记。再进行第二行,若当前列可访问,则重复以上操作,继续向下一行找。若当前行全部不可访问,则回溯到上一行,若成功放完最后一行,答案加一。注意思考如何判断某列某对角线是否可以放置.
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int Max = 10000001; int N; int Answer; bool visit [3][Max]; //visit[0][i]表示的是 当前列是否放皇后 visit[1][i]表示的是 一条对角线是否放皇后 int DFS (int cur) //visit[3][i] 表示的是 另一条对角线是否 放皇后 { if (cur == N) Answer++; // 如果当前行数cur 等于 限制行数 则是完成一次搜索, 答案加一 else for (int i = 0; i < N; i++) //枚举行数 { if (visit [0][i] == true && visit [1][cur + i] == true && visit [2][cur - i + N] == true) { visit [0][i] = visit [1][cur + i] = visit [2][cur - i + N] = false; //标记为已访问 DFS (cur + 1); //进行下一种情况 visit [0][i] = visit [1][cur + i] = visit [2][cur - i + N] = true ; //标记为未访问(回溯) } } } int main() { cin >> N; memset (visit ,true , sizeof (visit)); //将标志数组全部设置为可访问 DFS (0); cout << Answer ; return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明