1.自然语言描述
DFS(深度优先搜索)是一种搜索策略;在问题的状态空间树上进行深度优先遍历,即“一条路走到黑”,遇到行不通的路就回溯到父结点的搜索策略。问题数据规模较大时,还需要进行合适的剪枝操作来避免遍历一些不必要的状态。
2.代码描述
题目:Acwing.842 排列数字题目链接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=20;
int n,tra[MAXN];//tra记录状态
bool st[MAXN];//标记数组
void dfs(int u)
{
if(u==n){
for(int i=0;i<n;i++)//输出最终的可行解答案状态
cout<<tra[i]<<' ';
cout<<endl;
return;
}
for(int i=1;i<=n;i++){
if(!st[i]){//状态空间树的所有孩子
st[i]=true;
tra[u]=i;//记录状态
dfs(u+1);
st[i]=false;//回溯,还原现场,保证对u结点的下一个孩子结点的正确遍历
tra[u]=0;
}
}
return;
}
int main(void)
{
cin>>n;
dfs(0);
return 0;
}
题目:Acwing.843 N-皇后问题题目链接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=20;
int n;
char maze[MAXN][MAXN],col[MAXN],dg[MAXN],udg[MAXN];
//col[i]记录第i列是否已经有棋子
//表示对角线状态:利用截距之和相等则在同一条对角线上
//dg[u+i]表示下标为(u,i)的棋格副对角线方向是否已经有棋子(原点位于(0,0))
//udg[n-u+i]表示下标为(u,i)的棋格主对角线方向是否已经有棋子(原点位于(n,0))
void dfs(int u)
{
if(u==n){
for(int i=0;i<n;i++){//输出可行解答案状态
for(int j=0;j<n;j++)
cout<<maze[i][j];
cout<<endl;
}
cout<<endl;
return;
}
for(int i=0;i<n;i++){
if(!col[i]&&!dg[u+i]&&!udg[n-u+i]){
maze[u][i]='Q';
col[i]=dg[u+i]=udg[n-u+i]=1;
dfs(u+1);
col[i]=dg[u+i]=udg[n-u+i]=0;//回溯,恢复现场
maze[u][i]='.';
}
}
}
int main(void)
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
maze[i][j]='.';
dfs(0);//按行遍历
return 0;
}