<<算法很美>>——(六)——回溯算法(下)—N皇后问题

简介: <<算法很美>>——(六)——回溯算法(下)—N皇后问题

前言


首先我们来熟悉下前面学习的回溯框架:

  • 路径:就是我们当前做出的选择
  • 选择列表:就是我们当前可以做出的选择
  • 结束条件:也就是到达决策树底部,无法再做出选择
result=[]; 
def backtrack(路径,选择列表)
     if 满足结束条件: 
        result.add(路径);
        return 
    for 选择 in 选择列表 
        做选择
        backtrack(路径,选择列表)
        撤销选择

N皇后问题


image.png

这道题很经典,相信很多小伙伴都见过,并且挺畏惧的,今天我们就跟着我们前面学的模板走一遍,你会豁然开朗,更加深刻的理解对于这个模板·的运用


首先剖析题目:


就是给定n*n的棋盘,在上面放置n个棋子,并且保证同一行,同一列,左上角,左下角,右上角,右下角只有一个棋子,下面我们来画图分析

image.png

首先我们从第一行第一个格子走,会发现走到第二行就走不下去了,那我们就撤销退回去,另辟其路

image.png

到这里又不行了,又要去撤销往回退,第二行已经没法选了,只能撤销到第一行,重新选

image.png

成功了!!这只是一种情况,还要继续去找其他类,。这里就不再找下去了,有兴趣的同学可以下去试试通过上面的画图了解,应该有点思考了,【路径]不就是小于这些行已经成功放置的皇后嘛,【选择列表]某一行的所有列都是皇后的选择.(不过这里有一些限制条件,下面分析)【结束条件]当超过最后一行即可;这里我们来分析下限制条件check:

行和列很好看,主要分析下对角线上的

image.png

会发现左对角线 x-y=1; 右对角线:x+y=5; ok,到这里我们就分析结束了,下面我们来看代码吧

#include<iostream>
using namespace std;
//这里用4*4来做演示
int n = 4;
int ants;
int rec[4];
//bool check(int x, int y)
//{
//  for (int i = 0; i < n; i++)
//  {
//    if (rec[i] == y)//同一列
//    {
//      return false;
//    }
//    if (rec[i] + i == x + y)//右对角线
//    {
//      return false;
//    }
//    if (i - rec[i] == x - y)//左对角线
//    {
//      return false;
//    }
//  }
//  return true;
//}
void dfs(int row)//row当前处理的行
{
  if (row == n)//结束条件
  {
    ants++;
    return;
  }
  for (int col = 0; col < n; col++)
  {
    bool ok = true;
    for (int i = 0; i < row; i++)
    {
      //检查是否合法,与check一样
      if (rec[i] == col || i + rec[i] == row + col || rec[i] - i == col - row)
      {
        ok = false;
        break;
      }
    }
    if (ok)
    {
      rec[row] = col;//做选择
      dfs(row + 1);//进入下一行决策
      rec[row] = 0;//回溯,撤销选择
    }
  }
}
int main()
{
  dfs(0);
  cout << ants << endl;
  return 0;
}

牛刀小试


N皇后

最后总结


回溯算法就是个多叉树的遍历问题,关键就是在前序遍历和后序遍历的位置做一些操作,算法框架如下:

def backtrack(...):
    for 选择 in 选择列表:
        做选择
        backtrack(...)
        撤销选择

写 backtrack 函数时,需要维护走过的「路径」和当前可以做的「选择列表」,当触发「结束条件」时,将「路径」记入结果集。


某种程度上说,动态规划的暴力求解阶段就是回溯算法。只是有的问题具有重叠子问题性质,可以用 dp table 或者备忘录优化,将递归树大幅剪枝,这就变成了动态规划。而今天的两个问题,都没有重叠子问题,也就是回溯算法问题了,复杂度非常高是不可避免的。

image.png

相关文章
|
1月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
1月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构的基本概念;算法的基本概念、特性以及时间复杂度、空间复杂度等举例说明;【含常见的报错问题及其对应的解决方法】
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
|
算法
”回溯算法“框架及练习题
”回溯算法“框架及练习题
42 0