深度优先搜索的学习
2016-02-05 14:18
225 查看
解决深度优先搜索关键在于“当下该如何做”到”下一步该如何做“。
通常是把每一种方法都尝试一遍,当这一步解决后进行下一步。
基本模型:
举例:
输入一个数n,输出1~n的全排列
再举个例子:
有数字1~9,使得???+???+???=???成立
利用深度优先搜索走迷宫
如输入:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
结果为 7
通常是把每一种方法都尝试一遍,当这一步解决后进行下一步。
基本模型:
void dfs(int step) { 判断边界 尝试每一种可萌 for(int i=1;i<=n;i++){ 继续下一步 } 返回 }
举例:
输入一个数n,输出1~n的全排列
/*全排列问题,举个例子就是有几张牌放在几个不同盒子里,有多少种情况*/ #include<iostream> using namespace std; int a[10], book[10], n;//a是牌,book是盒子,当book为1时说明有牌 void dfs(int step) { if (step == n + 1) {//当在第n+1和盒子时说明已经排完 for (int i = 1; i <= n; i++) { cout << a[i];//输出牌 } cout << endl; return;//返回上一次调用时的dfs函数 } for (int i = 1; i <= n; i++) { if (book[i] == 0) {//判断是否可以放牌 a[step] = i; book[i] = 1;//标记 dfs(step + 1);//递归,进行下一个盒子 book[i] = 0;//每次放完牌记得要清零 } } return; } int main() { cout << "输入盒子个数" << endl; cin >> n; dfs(1);//从第一个盒子开始 return 0; }
再举个例子:
有数字1~9,使得???+???+???=???成立
/*与盒子里放牌是一个道理*/ #include<iostream> using namespace std; int a[10], book[10], total = 0;//total是有几种可能 void dfs(int step) { if (step == 10) { if (a[1] * 100 + a[2] * 10 + a[3] + a[4] * 100 + a[5] * 10 + a[6] == a[7] * 100 + a[8] * 10 + a[9]) { total++; cout << a[1] << a[2] << a[3] << "+" << a[4] << a[5] << a[6] << "=" << a[7] << a[8] << a[9] << endl; } return; } for (int i = 1; i < 10; i++) { if (book[i] == 0) { a[step] = i; book[i] = 1; dfs(step + 1); book[i] = 0; } } return; } int main() { dfs(1); cout << "一共有" << total << "种可能" << endl; return 0; }
利用深度优先搜索走迷宫
/*利用深度优先搜索走迷宫, 输入迷宫时0代表可以走,1代表不能走, 求最短路径*/ #include<iostream> using namespace std; int a[51][51];//迷宫 int book[51][51];//用来存储走过的点 int min = 999999;//步数的最小值 int p, q,m,n; void dfs(int x, int y, int step) { int next[4][2] = {//行走的坐标 {0,1},//向右 {1,0},//向下 {0,-1},//向左 {-1,0}//向右 }; int next_x, next_y;//下一步的坐标 if (x == p&&y == q) {//判断是否完成 if (step < min) min = step;//保存最小步数 return;//注意要返回上一次 } for (int i = 0; i < 4; i++) {//四种走法 next_x = x + next[i][0]; next_y = y + next[i][1]; if (next_x < 1 || next_x>n || next_y < 1 || next_y>m)//判断越界 continue; if (a[next_x][next_y] == 0 && book[next_x][next_y] == 0) {//判断是否能走 book[next_x][next_y] = 1;//标记走过的点 dfs(next_x, next_y, step + 1);//递归,进行下一步 book[next_x][next_y] = 0;//清零 } } return; } int main() { int start_x, start_y; cout << "输入行和列" << endl; cin >> n >> m; cout << "输入迷宫" << endl; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) cin >> a[i][j]; } cout << "输入起始坐标X" << endl; cin >> start_x; cout << "输入起始坐标Y" << endl; cin >> start_y; cout << "输入终点坐标X" << endl; cin >> p; cout << "输入终点坐标Y" << endl; cin >> q; book[start_x][start_y] = 1;//要把起点标记上,防止走重 dfs(start_x, start_y, 0);//起始步数为零 cout << min<<endl; return 0; }
如输入:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
结果为 7
相关文章推荐
- poj1419——Graph Coloring(dfs)
- [转] 转载:一条网线,不用路由器,多台笔记本电脑共享上网
- 深入浅出Windows BATCH
- HDU 1028 (dp)
- poj1273 2010.2.17
- 固定导航(Sticky nav)
- C++暑期学习笔记
- 《HTTP权威指南》学习笔记——URL和资源
- Google protocol-buffers java版--简单使用
- iOS开发之苹果公司联系邮箱大全
- HDU 1018 big numbe
- 计算机网络的特点及性能
- win10、win7系统64位oracle11g安装教程以及32位plsql连接教程
- poj1221 2010.2.17
- 项目中遇到的问题
- 蓝桥杯学习记录-基础练习
- linux命令行下如何以目录树的形式显示一个文件夹的所有文件
- 通知:转移至简书
- PAT (Basic Level)1009. 说反话
- Angular-JS初见