【搜索】dfs(回溯、剪枝、记忆化)

在这里插入图片描述

个人主页:Guiat
归属专栏:我讲你听

在这里插入图片描述

文章目录

  • 1. dfs 回溯
    • 1.1 回溯介绍
    • 1.2 回溯模板
    • 1.3 回溯经典题目
  • 2. dfs 剪枝
    • 2.1 剪枝介绍
    • 2. 2 剪枝模板
    • 2.3 经典题目
  • 3. dfs 记忆化
    • 3.1 记忆化介绍
    • 3.2 记忆化示例

正文

1. dfs 回溯

1.1 回溯介绍

  • 核心思想:通过试错的方式探索所有可能得解,当发现当前路径无法得到有效解时,撤销(回溯)最近一步的选择,尝试其他分支。

  • 关键步骤

    • 选择:在当前步骤做出一个选择。
    • 递归:基于这个选择进入下一层决策。
    • 撤销(回溯):如果当前路径不满足条件,回退到上一步,尝试其他选择。

【注】实际上,回溯算法比较灵活,需要具体情况具体分析。

1.2 回溯模板

【求 1 ~ n 的全排列 】

#include <iostream>
#define IOS ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);using namespace std;const int N = 1e5 + 10;
int n, a[N]; bool vis[N];// 回溯
void dfs(int deep)
{if (deep == n + 1){for (int i = 1; i <= n; i ++) cout << a[i] << " \n"[i == n];return ;}for (int i = 1; i <= n; i ++){if (vis[i]) continue;vis[i] = true; a[deep] = i;dfs(deep + 1); vis[i] = false;}
}void solve()
{cin >> n; dfs(1);
}int main()
{IOS; int _ = 1; // cin >> _;while (_ --) solve();return 0;
}

1.3 回溯经典题目

【题目】N 皇后

【AC_Code】

#include <iostream>
#define IOS ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);using namespace std;const int N = 30;
int n, ans; bool vis[N][N];void dfs(int deep)
{if (deep == n + 1) { ans ++; return ; }for (int i = 1; i <= n; i ++){if (vis[0][i] || vis[1][deep + i] || vis[2][deep - i + n]) continue;// 修改状态vis[0][i] = true;vis[1][deep + i] = true;vis[2][deep - i + n] = true;dfs(deep + 1);// 恢复现场vis[0][i] = false;vis[1][deep + i] = false;vis[2][deep - i + n] = false;}
}void solve()
{cin >> n; dfs(1); cout << ans << '\n';
}int main()
{IOS;int _ = 1; // cin >>  _;while (_ --) solve();return 0;
}

2. dfs 剪枝

2.1 剪枝介绍

  • 因为搜索过程构成了一棵树,剔除不必要的部分,就像是在树上将树枝剪掉,故名剪枝。
  • 核心思想:通过某些条件或规则,提前终止某些不可能产生最优解的分支,从而减少不必要的计算。
  • 剪枝是回溯法的一种重要优化手段。

2. 2 剪枝模板

void backtracking(参数)
{if (终止条件){存储结果;  // 找到一个有效解return;}for (选择 : 所有可能的选择){if (剪枝条件) continue;  // 跳过当前选择,进行剪枝做出选择;  // 处理当前选择backtracking(新参数);  // 递归进入下一层撤销选择;  // 回溯,撤销当前选择}
}

2.3 经典题目

【题目】数字王国之军训排队

【AC_Code】

#include <iostream>
#include <vector>
#include <algorithm>
#define IOS ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);using namespace std;const int N = 15;
int n, a[N]; vector<int> vec[N];bool dfs(int deep, int cnt)
{if (deep == n + 1) return true;for (int i = 0; i < cnt; i ++){bool flag = false;for (const auto &num : vec[i]){if (a[deep] % num == 0) { flag = true; break; }}if (flag) continue;vec[i].push_back(a[deep]);if (dfs(deep + 1, cnt)) return true;// 恢复现场vec[i].pop_back(); }return false;
}void solve()
{cin >> n; for (int i = 1; i <= n; i ++) cin >> a[i];sort(a + 1, a + n + 1);for (int cnt =  1; cnt <= n; cnt ++){if (dfs(1, cnt)) { cout << cnt << '\n'; break; }}
}int main()
{IOS;int _ = 1; // cin >>  _;while (_ --) solve();return 0;
}

3. dfs 记忆化

3.1 记忆化介绍

  • 记忆化是一种优化技术,主要用于加速递归算法或动态规划算法。
  • 核心思想:通过缓存(或"记忆")已经计算过的结果,避免重复计算,从而减少算法的运行时间。

3.2 记忆化示例

【计算斐波那契数列】

#include <iostream>
#include <cstring>
#include <algorithm>
#define IOS ios :: sync_with_stdio(0); cin.tie(0); cout.tie(0);using namespace std;
using ll = long long;const ll N = 1e5 + 10, p = 1e9 + 7, inf = 1e9; ll dp[N];ll fun(int n)
{if (n <= 2) return 1;if (dp[n] != -1) return dp[n];return dp[n] = (fun(n - 1) + fun(n - 2)) % p;
}void solve()
{memset(dp, -1, sizeof dp); int n; cin >> n; cout << fun(n) << '\n';
}int main()
{IOS;int _ = 1; // cin >>  _;while (_ --) solve();return 0;
}

结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38781.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

emWin自定义键盘布局

emWin V6.46提供了自带的键盘控件&#xff0c;用起来功能还是比较齐全的。但是有些时候自带的布局不能满足要求&#xff0c;此时可用键盘的结构体来自定义布局。 KEYDEF_KEYBOARD MyNumPad;static KEYDEF_AREA NumPadKeyArea[4] {{10, 0, 720, 250}, //每行按钮的坐标和占用…

人工智能之数学基础:瑞利商与特征值的关系

本文重点 瑞利商是线性代数中的一个重要概念,具有丰富的性质和广泛的应用。通过求解瑞利商的最大值或最小值,可以找到矩阵的特征值和特征向量,进而解决降维、聚类、优化和计算机视觉等领域的问题。广义瑞利商作为瑞利商的推广形式,在机器学习和数据分析中也发挥着重要作用…

Mysql配套测试之更新篇

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 测试准备&#xff1a; 更新测试 &#xff1a; 1.将孙悟空同学的数学成…

2025年如何避免使用验证码求解器时被IP封禁

引言 2025年&#xff0c;验证码求解器已成为自动化网络抓取和其他在线流程的关键工具。然而&#xff0c;自动化用户面临的一个常见挑战是IP封禁。当网站检测到自动化活动时&#xff0c;通常会阻止发出请求的IP地址&#xff0c;导致验证码挑战无法解决。本文将探讨使用验证码求…

ElasticSearch 可观测性最佳实践

ElasticSearch 概述 ElasticSearch 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别&#xff08;大数据时代&#xff09;的数据。ES 也使用 Java 开…

操作系统的特征

并发 指两个或多个事件在同一时间间隔内发生。这些时间宏观上是同时发生的&#xff0c;但微观上是交替发生的。 并行 指两个或多个事件在同一时刻同时发生 操作系统的并发性 指计算机系统重“同时”运行着多个程序&#xff0c;这些程序宏观上看是同时运行的&#xff0c;而…

数据结构——B树、B+树、哈夫曼树

目录 一、B树概念1.B树的构造2 .B树的特点 二、B树概念1.B树构造2.B树的特点 三、B树和B树的区别四、哈夫曼树1.哈夫曼树的基本概念2.哈夫曼树的构建 一、B树概念 B树的出现是为了弥合不同的存储级别之间的访问速度上的巨大差异&#xff0c;实现高效的 I/O。平衡二叉树的查找效…

电子签的法律效力、业务合规与监管难点

撰稿 | 区长 来源 | 贝多财经 据2025年央视“3.15”晚会报道&#xff0c;借贷宝、人人信等平台上存在高利贷的情形。放贷人与借款人在平台签署借款合同&#xff0c;但是实际借款金额低于合同金额&#xff0c;从而绕开平台对利率的限制。这引发了人们对电子签法律效力、业务合…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

体育直播视频源格式解析:M3U8 vs FLV

在体育直播领域&#xff0c;视频源的格式选择直接影响着直播的流畅度、画质以及兼容性。目前&#xff0c;M3U8 和 FLV 是两种最为常见的视频流格式&#xff0c;它们各有优劣&#xff0c;适用于不同的场景。本文将从技术原理、优缺点以及应用场景等方面对 M3U8 和 FLV 进行详细解…

【动态规划】下降路径最小和

跟之前不同由于可能取到最右上角值&#xff0c;则左右各加一列&#xff0c;并且由于求最小值&#xff0c;则加的列须设置为正无穷大&#xff1b; class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int nmatrix.size();vector<…

07_GRU模型

GRU模型 双向GRU笔记:https://blog.csdn.net/weixin_44579176/article/details/146459952 概念 GRU&#xff08;Gated Recurrent Unit&#xff09;也称为门控循环单元&#xff0c;是一种改进版的RNN。与LSTM一样能够有效捕捉长序列之间的语义关联&#xff0c;通过引入两个&qu…

VScode

由于centos停止了维护 ,后面使用ubuntu 在Ubuntu中用vscode 充当记事本的作用 替代了centos中vim的作用 后面使用vscode编辑 vscode中继续使用makefile , xshell中的cgdb进行debug (半图形写 ,半命令行debug&&运行) 官网下载地址&#xff1a;https://code.visuals…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

异步编程与流水线架构:从理论到高并发

目录 一、异步编程核心机制解析 1.1 同步与异步的本质区别 1.1.1 控制流模型 1.1.2 资源利用对比 1.2 阻塞与非阻塞的技术实现 1.2.1 阻塞I/O模型 1.2.2 非阻塞I/O模型 1.3 异步编程关键技术 1.3.1 事件循环机制 1.3.2 Future/Promise模式 1.3.3 协程&#xff08;Cor…

python-selenium 爬虫 由易到难

本质 python第三方库 selenium 控制 浏览器驱动 浏览器驱动控制浏览器 推荐 edge 浏览器驱动&#xff08;不容易遇到版本或者兼容性的问题&#xff09; 驱动下载网址&#xff1a;链接: link 1、实战1 &#xff08;1&#xff09;安装 selenium 库 pip install selenium&#…

前端OOM内存泄漏如何排查?

前言 现代前端开发中&#xff0c;随着应用的复杂性和交互性的增加&#xff0c;OOM&#xff08;Out Of Memory&#xff0c;内存不足&#xff09;问题和内存泄漏逐渐成为影响用户体验和应用性能的关键挑战。排查和解决这些问题需要开发人员具备良好的调试技巧和优化策略。 造成…

C++20:玩转 string 的 starts_with 和 ends_with

文章目录 一、背景与动机二、string::starts_with 和 string::ends_with&#xff08;一&#xff09;语法与功能&#xff08;二&#xff09;使用示例1\. 判断字符串开头2\. 判断字符串结尾 &#xff08;三&#xff09;优势 三、string_view::starts_with 和 string_view::ends_w…

Redis、Memcached应用场景对比

环境 Redis官方网站&#xff1a; Redis - The Real-time Data Platform Redis社区版本下载地址&#xff1a;Install Redis | Docs Memcached官方网站&#xff1a;memcached - a distributed memory object caching system Memcached下载地址&#xff1a;memcached - a dis…

【MySQL】日志

目录 基本概念错误日志二进制日志查询日记慢查询日志 基本概念 日志&#xff08;Log&#xff09;是系统、软件或设备在运行过程中对发生的事件、操作或状态变化所做的记录。这些记录通常包含时间戳、事件类型、相关数据等信息&#xff0c;用于跟踪运行过程、排查故障、审计操作…