赞
踩
所谓的DFS就是深度优先遍历,一条路走到黑,走到无路可走了才会选择回头,
DFS俗称爆搜,深搜,最重要的就是我们按照什么顺序来把题目全部遍历一下。DFS对应的流程是一个树的结构,DFS的精髓在于递归求解的思路以及回溯的处理。针对搜索的过程,又有重要的剪枝优化。必要的剪枝优化对DFS的顺序执行有很大的作用。
DFS的过程就是沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都搜过,搜索回溯到发现节点v的那条边的起始节点。
DFS使用的数据结构是栈,时间复杂度是O(n),DFS不具有最短性,也就是DFS搜到的路径不一定是最短路。
function dfs(当前状态){
if(当前状态 == 目的状态){
···
}
for(···寻找新状态){
if(状态合法){
vis[访问该点];
dfs(新状态);
?是否需要恢复现场->vis[恢复访问]
}
}
if(找不到新状态){
···
}
}
剪枝是在不跳过最优解的情况下,采取必要的手段跳过不含有最优解的分支,减少搜索的次数,减少程序运行的时间。
剪枝优化这里就不赘述了。可以看这里DFS对剪枝的补充_真的没事鸭的博客-CSDN博客
给定一个整数 nn,将数字 1∼n 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
输入格式
共一行,包含一个整数 n。
输出格式
按字典序输出所有排列方案,每个方案占一行。
数据范围
1≤n≤7
输入样例:
3
输出样例:
1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
利用DFS一层一层搜,搜完了就回溯,然后再根据结束条件判断是否搜索完毕
- #include <iostream>
- using namespace std;
- const int N=10;
- int p[N];
- int n;
- bool st[N];
- void dfs(int u)
- {
- //结束条件
- if(u>n)
- {
- for(int i=1;i<=n;i++)
- cout<<p[i]<<" ";
- cout<<endl;
- return;
- }
- //寻找新节点
- for(int i=1;i<=n;i++)
- {
- //判断是否合法
- if(!st[i])
- {
- p[u]=i;
- st[i]=true;
- dfs(u+1);
- st[i]=false;
- }
- }
- }
- int main()
- {
- cin>>n;
- dfs(1);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。