万能的搜索——深度优先搜索Depth-First-Search

『什么是搜索』


百度百科的定义

搜索算法是利用计算机的高性能来有目的的穷举一个问题解空间的部分或所有的可能情况,从而求出问题的解的一种方法。

【搜索树】

  • 将搜索的过程中每一步的状态变成树的一个结点
  • 根结点为搜索的初始状态
  • 搜索是不断拓展这棵树,直到找到目标状态为止

『深度优先搜索』


顾名思义,优先向搜索树"深"层搜索的搜索的算法.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。

主要算法过程:对于一个合法的状态A,对于其所有的子状态(搜索树的儿子结点),选择一种进行探索,递归这一过程,直到到达叶子结点或目前状态不合法,则回溯到父亲结点,对另一种子状态进行搜索。

【伪代码】

void dfs(状态A){

    if(A不合法)
        return;
    if(A为目标状态)//判断边界
        输出;
    if(A不为目标状态但是合法)//继续下一步,递归调用
        dfs(A+1);


}

【动态图】

è¿éåå¾çæè¿°

『上题上题』


【八皇后问题】

该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 

『代码代码』

//这里写的是n皇后
#include <iostream>
#include <algorithm>
using namespace std;
int n,tot=0,C[9];//C[x]表示第x行的编号   tot表示解法的个数
void dfs(int step){
	if(step == n)//递归的边界.只要走到这里,所有皇后必然不冲突
		tot++;
	else
		for(int i = 0; i < n; i++){
			int ok = 1;//判断是否合法
			C[step] = i;//尝试把第step行的皇后放在第i列
            //逐行放置所以只需要检查是否纵向和对角线攻击
			for(int j = 0; j < step; j++)//检查是否和前面的皇后冲突,
                //step-C[step] == j-C[j]判断主对角线, step+C[step] == j+C[j]判断副对角线
				if(C[step] == C[j] || step-C[step] == j-C[j] || step+C[step] == j+C[j]){
					ok = 0; break;
				}
			if(ok)//如果合法,继续递归
				dfs(step+1);
		}
}
int main(){
	cin>>n;//这里输入8就可以解决八皇后问题
	dfs(0); 
	cout<<tot;
	return 0;
}

                                                                                                         

    格子(x,y)的y-x标注了主对角线                                                                                                                   格子(x,y)的x+y标注了副对角线

#include <iostream>
#include <algorithm>
using namespace std;
int n,tot=0,vis[2][100];
void dfs(int step){
	if(step == n)
		tot++;
	else
		for(int i = 0; i < n; i++){
			if(!vis[0][i] && !vis[1][step+i] && !vis[2][step-i+n]){//利用二维数组直接判断 
				vis[0][i] = vis[1][step+i] = vis[2][step-i+n] = 1;//修改全局变量 
				dfs(step+1);
				vis[0][i] = vis[1][step+i] = vis[2][step-i+n] = 0;//将全局变量改过来 
			}
		}
}
int main(){
	cin>>n;
	dfs(0); 
	cout<<tot;
	return 0;
}

『感悟』

深搜最重要的是回溯,即递归函数不再递归它自己,而是返回上一层调用。

扫描二维码关注公众号,回复: 2592741 查看本文章

刚查了离散成绩 orz

猜你喜欢

转载自blog.csdn.net/sinat_40872274/article/details/81227270