搜索

              深度优先搜索

关于深搜的一些复习

首先明确什么是深搜。

深搜,即为深度优先搜索。

思想为:为了求得问题的解,先选择一种情况进行,如果情况可行,则继续向下寻找。若不可行,则返回上一层,选择另一种情况,再进行寻找,如此反复,直到得出答案或无解。

        基本框架

              

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;
}

 

                

posted @ 2016-11-08 08:38  ZlycerQan  阅读(195)  评论(0编辑  收藏  举报