1.动态回溯:
(寻路算法 深度寻路算法)
2.动态回溯算法思想:
① 针对问题来解空间: 根据实际需求用不同方式来描述
深度寻路算法: 要找到起点到终点的路径 二维数组来描述地图
② 确定易于搜索的解空间结构,并构造相应的判断函数
③ 用深度优先搜索的方式来解决问题,并要有合适的回溯方式(栈)动态回溯 == 问题的解空间 + 深度优先搜索 + 判断结果的结构 + 回溯
3.动态回溯一般用来解决哪些问题:
① 寻路 ②货物装载 ③0-1背包问题 ④图的着色问题(涂格子)
⑤电路排版问题 ⑥ 旅行者售后员问题 ⑦N皇后问题
8皇后问题: 国际象棋棋盘 在任意两个皇后不能互相触及的前提下 有多少种摆法
1 问题的解空间 : 二维数组
2 深度优先搜索 : 递归 一个个去摆 摆了N个皇后结束
3 判断结果 : 判断能不能摆 数量是否达标
4 回溯 : 给二维数组元素赋值 为1 表示摆放好了 赋值为0 就是回退
- // N皇后问题.cpp : 定义控制台应用程序的入口点。
- //
- #include
- #define TEST 1
-
- #define N 4
- //用来记录有多少种解法
- int cnt = 0;
-
- //遍历整个棋盘
- void travel(int Q[N][N]);
-
- //N皇后问题
- void Queen(int j, int Q[N][N]);
-
- //判断 i j 位置是否能放皇后 如果能 返回true 否则 返回false
- bool isOkPos(int i, int j, int Q[N][N]);
-
- int main()
- {
- int Q[N][N] = { 0 };//0表示没有放皇后 1表示放了皇后
- Queen(0, Q);
- printf("解法种数为:%d\n", cnt);
- return 0;
- }
-
- //N皇后问题
- void Queen(int j, int Q[N][N])
- {
- if (N == j)
- {//N个皇后都已经放置好了
- #if TEST
- travel(Q);//遍历整个地图
- #endif
- cnt++;
- return;
- }
- for (int i = 0; i < N; i++)
- {//y坐标
- if (isOkPos(i, j, Q))
- {//能放
- Q[i][j] = 1;//放
- Queen(j + 1, Q);//放下一个
- Q[i][j] = 0;//回溯
- }
- }
- }
-
- //遍历整个棋盘
- void travel(int Q[N][N])
- {
- printf("-------------------------------------------\n");
- for (int i = 0; i < N; i++)
- {
- for (int j = 0; j < N; j++)
- {
- printf("%d ", Q[i][j]);
- }
- printf("\n");
- }
- printf("-------------------------------------------\n");
- }
-
- //判断 i j 位置是否能放皇后 如果能 返回true 否则 返回false
- bool isOkPos(int i, int j, int Q[N][N])
- {
- int s;//s i 垂直 y轴
- int t;//t j 水平 x轴
-
- //横向判断
- for (s = i, t = 0; t < N; t++)
- {
- if (Q[s][t] == 1 && j != t) return false;
- }
- //纵向判断
- for (t = j, s = 0; s < N; s++)
- {
- if (Q[s][t] == 1 && s != i) return false;
- }
-
- //左上
- for (t = j - 1, s = i - 1; s >= 0 && t >= 0; s--, t--)
- {
- if (Q[s][t] == 1) return false;
- }
-
- //左下
- for (t = j - 1, s = i + 1; s < N && t >= 0; s++, t--)
- {
- if (Q[s][t] == 1) return false;
- }
-
- //右上
- for (t = j + 1, s = i - 1; s >=0 && t < N; s--, t++)
- {
- if (Q[s][t] == 1) return false;
- }
- //右下
- for (t = j + 1, s = i + 1; s < N && t < N; s++, t++)
- {
- if (Q[s][t] == 1) return false;
- }
- return true;
- }