• Day22:算法篇之动态回溯


    一、动态回溯相关

    1.动态回溯:

    (寻路算法    深度寻路算法)

    2.动态回溯算法思想:

            ① 针对问题来解空间:  根据实际需求用不同方式来描述
                深度寻路算法: 要找到起点到终点的路径   二维数组来描述地图
            ② 确定易于搜索的解空间结构,并构造相应的判断函数
            ③ 用深度优先搜索的方式来解决问题,并要有合适的回溯方式(栈)

        动态回溯 == 问题的解空间 + 深度优先搜索 + 判断结果的结构 + 回溯

    3.动态回溯一般用来解决哪些问题:

       ① 寻路  ②货物装载  ③0-1背包问题      ④图的着色问题(涂格子)
       ⑤电路排版问题    ⑥ 旅行者售后员问题   ⑦N皇后问题

    二、典例----N皇后问题分析

    1.问题规则+算法流程分析       

     8皇后问题: 国际象棋棋盘   在任意两个皇后不能互相触及的前提下 有多少种摆法
        
        1 问题的解空间 : 二维数组
        2 深度优先搜索 : 递归 一个个去摆  摆了N个皇后结束
        3 判断结果     : 判断能不能摆  数量是否达标
        4 回溯        :  给二维数组元素赋值 为1 表示摆放好了 赋值为0 就是回退  

    2.代码实现

    1. // N皇后问题.cpp : 定义控制台应用程序的入口点。
    2. //
    3. #include
    4. #define TEST 1
    5. #define N 4
    6. //用来记录有多少种解法
    7. int cnt = 0;
    8. //遍历整个棋盘
    9. void travel(int Q[N][N]);
    10. //N皇后问题
    11. void Queen(int j, int Q[N][N]);
    12. //判断 i j 位置是否能放皇后 如果能 返回true 否则 返回false
    13. bool isOkPos(int i, int j, int Q[N][N]);
    14. int main()
    15. {
    16. int Q[N][N] = { 0 };//0表示没有放皇后 1表示放了皇后
    17. Queen(0, Q);
    18. printf("解法种数为:%d\n", cnt);
    19. return 0;
    20. }
    21. //N皇后问题
    22. void Queen(int j, int Q[N][N])
    23. {
    24. if (N == j)
    25. {//N个皇后都已经放置好了
    26. #if TEST
    27. travel(Q);//遍历整个地图
    28. #endif
    29. cnt++;
    30. return;
    31. }
    32. for (int i = 0; i < N; i++)
    33. {//y坐标
    34. if (isOkPos(i, j, Q))
    35. {//能放
    36. Q[i][j] = 1;//放
    37. Queen(j + 1, Q);//放下一个
    38. Q[i][j] = 0;//回溯
    39. }
    40. }
    41. }
    42. //遍历整个棋盘
    43. void travel(int Q[N][N])
    44. {
    45. printf("-------------------------------------------\n");
    46. for (int i = 0; i < N; i++)
    47. {
    48. for (int j = 0; j < N; j++)
    49. {
    50. printf("%d ", Q[i][j]);
    51. }
    52. printf("\n");
    53. }
    54. printf("-------------------------------------------\n");
    55. }
    56. //判断 i j 位置是否能放皇后 如果能 返回true 否则 返回false
    57. bool isOkPos(int i, int j, int Q[N][N])
    58. {
    59. int s;//s i 垂直 y轴
    60. int t;//t j 水平 x轴
    61. //横向判断
    62. for (s = i, t = 0; t < N; t++)
    63. {
    64. if (Q[s][t] == 1 && j != t) return false;
    65. }
    66. //纵向判断
    67. for (t = j, s = 0; s < N; s++)
    68. {
    69. if (Q[s][t] == 1 && s != i) return false;
    70. }
    71. //左上
    72. for (t = j - 1, s = i - 1; s >= 0 && t >= 0; s--, t--)
    73. {
    74. if (Q[s][t] == 1) return false;
    75. }
    76. //左下
    77. for (t = j - 1, s = i + 1; s < N && t >= 0; s++, t--)
    78. {
    79. if (Q[s][t] == 1) return false;
    80. }
    81. //右上
    82. for (t = j + 1, s = i - 1; s >=0 && t < N; s--, t++)
    83. {
    84. if (Q[s][t] == 1) return false;
    85. }
    86. //右下
    87. for (t = j + 1, s = i + 1; s < N && t < N; s++, t++)
    88. {
    89. if (Q[s][t] == 1) return false;
    90. }
    91. return true;
    92. }

     

  • 相关阅读:
    jquery 滚动条滚动到底部触发事件
    生活不止有诗和远方,也有眼前的美好。也许你心里有清风明月,
    【云原生】Kubernetes核心技术(中)
    TCP 时间戳妙用
    【C++位图】1. 快速查找某个数据是否在一个集合中 2. 排序(全部插入,遍历一遍) 3. 求两个集合的交集、并集等
    基于springboot实现游戏分享网站系统项目【项目源码+论文说明】计算机毕业设计
    JavaEE:进程调度的基本过程
    哪些品牌蓝牙耳机适合学生党?平价又好用的蓝牙耳机推荐
    WPF上位机通信组件与Modbus协议
    【HarmonyOS】【ArkUI】在Service中使用Emitter
  • 原文地址:https://blog.csdn.net/zjjaibc/article/details/126616422