【算法】递归型枚举与回溯剪枝初识
递归型枚举与回溯剪枝初识
- 1.枚举子集
- 2.组合型枚举
- 3.枚举排列
- 4.全排列问题
- 什么是搜索?搜索,是一种枚举,通过穷举所有的情况来找到最优解,或者统计合法解的个数。因此,搜索有时候也叫作暴搜。搜索一般分为深度优先搜索(DFS)与宽度优先搜索(BFS)。
- 深度优先遍历 vs 深度优先搜索,宽度优先遍历 vs 宽度优先搜索。遍历是形式,搜索是目的。不过,在一般情况下,我们不会去纠结概念的差异,两者可以等同。
- 回溯与剪枝
- 回溯:当在搜索的过程中,遇到走不通或者走到底的情况时,就回头。
- 剪枝:在搜索过程中,剪掉重复出现或者不是最优解的分。
递归型枚举与回溯剪枝初识:
- 画决策树。
- 根据决策树写递归。
搜索的本质:对决策树进行一次遍历,直到将所有的情况搜集到为止。
1.枚举子集
B3622 枚举子集(递归实现指数型枚举)

解法:深搜
设一共有 3 人,分别是 1,2,3。「从前往后」考虑每一个人,针对当前这个人「选」或者「不选」,我们可以画出如下「决策树」:

设计递归函数:
- 重复子问题:针对某一位,「选」或者「不选」。因为最终结果要按照「字典序」输出,我们可以「先考虑不选」,然后「再考虑选」。
- 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#include<iostream>
#include<string>
using namespace std;const int N = 11;int n;
string path; //记录递归过程中,每⼀步的决策void dfs()
{if(path.size() == n){cout << path << endl; //path存着前n个⼈的决策 return;}//不选path += 'N';dfs();path.pop_back(); //回溯:恢复现场//选path += 'Y';dfs(); path.pop_back(); //回溯:恢复现场
}int main()
{cin >> n;dfs();return 0;
}
2.组合型枚举
P10448 组合型枚举

解法:深搜
设 n = 4, m = 3,「从前往后」考虑 3 个位置应该选哪个数,我们可以画出如下决策树:

设计递归函数:
- 重复子问题:当前这一位,应该放哪个数上去。因为这是一个「组合」问题,不涉及排列,所以我们当前位置开始放的数,应该是「上次决策的数的下一位」。
- 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#include<iostream>
#include<vector>
using namespace std;int n, m;
vector<int> path; //记录递归过程中,每⼀步的决策void dfs(int pos)
{if(path.size() == m){for(auto& e : path) cout << e << " ";cout << endl;return;}for(int i = pos; i <= n; i++){path.push_back(i);dfs(i + 1);path.pop_back(); //回溯:恢复现场}
}int main()
{cin >> n >> m;dfs(1);return 0;
}
3.枚举排列
B3623 枚举排列(递归实现排列型枚举)

解法:深搜
设 n = 3, k = 2,一共要选出两个数,可以依次「考虑要选出来的数」是谁,画出如下决策树:

设计递归函数:
- 重复子问题:考虑这一位要放上什么数。因为是「排列」问题,所以我们直接从 1 开始枚举要放的数。
- 剪枝:在这一条路径中,我们「不能选择之前已经选择过的数」,需要用到辅助数组。
- 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#include<iostream>
#include<vector>
using namespace std;const int N = 15;int n, k;
vector<int> path; //记录递归过程中,每⼀步的决策
bool vis[N]; //辅助数组:标记哪些数已经选过 void dfs()
{if(path.size() == k){for(auto& e : path) cout << e << " ";cout << endl;return;}for(int i = 1; i <= n; i++){if(vis[i] == false){vis[i] = true;path.push_back(i);dfs();//回溯:恢复现场path.pop_back();vis[i] = false;}}
}int main()
{cin >> n >> k;dfs();return 0;
}
4.全排列问题
P1706 全排列问题

解法:深搜
跟上一道题的决策一样,我们可以枚举每一位应该放上什么数,只不过少了 k 的限制。剪枝的策略还是一样的,那就是在路径中,「不能选择之前已经选过的数」。

#include<iostream>
#include<vector>
using namespace std;const int N = 15;int n;
vector<int> path; //记录递归过程中,每⼀步的决策
bool vis[N]; //辅助数组:标记哪些数已经选过void dfs()
{if(path.size() == n){for(auto& e : path) printf("%5d", e);cout << endl;return;}for(int i = 1; i <= n; i++){if(vis[i] == false){vis[i] = true;path.push_back(i);dfs();//回溯:恢复现场path.pop_back();vis[i] = false;}}
}int main()
{cin >> n;dfs();return 0;
}
相关文章:
【算法】递归型枚举与回溯剪枝初识
递归型枚举与回溯剪枝初识 1.枚举子集2.组合型枚举3.枚举排列4.全排列问题 什么是搜索?搜索,是一种枚举,通过穷举所有的情况来找到最优解,或者统计合法解的个数。因此,搜索有时候也叫作暴搜。搜索一般分为深度优先搜索…...
pytorch 多机多卡训练方法
在深度学习训练中,使用多机多卡(多台机器和多块 GPU)可以显著加速模型训练过程。 PyTorch 提供了多种方法来实现多机多卡训练,以下是一些常用的方法和步骤: 1. 使用 torch.distributed 包 PyTorch 的 torch.distribut…...
InfiniBand客户端注册机制详解:ib_register_client函数的作用与实现
在Linux内核的InfiniBand(IB)子系统中,ib_register_client函数扮演着至关重要的角色。它允许上层用户(如特定的IB设备驱动程序或相关应用模块)注册为IB客户端,并定义在IB设备添加或移除时应执行的回调函数。这一机制确保了IB设备的动态管理,以及资源的有效分配和回收。本…...
rocketmq-product-send方法源码分析
先看有哪些send方法 首先说红圈的 有3个红圈。归类成3种发送方式。假设前提条件,发送的topic,有3个broker,每个broker总共4个write队列,总共有12个队列。 普通发送。负载均衡12个队列。指定超时时间指定MessageQueue,发送&#…...
centos下设置服务器开机自启动 redis
在客户服务器中,服务器重启,发现 Redis 没有重启, 可以按照类似的步骤来创建自启动脚本,并将它添加到定时任务中。 解决办法: 1. 创建自启动脚本 进入服务器并创建脚本文件,例如 /usr/local/bin/redis_…...
【Linux】APT 密钥管理:官方推荐的解决方案应对 apt-key 弃用
引言 在 Ubuntu 和 Debian 系统中,apt-key 命令用于管理 GPG 密钥,验证来自软件包存储库的包是否合法并且未被篡改。然而,从 Debian 11 和 Ubuntu 22.04 开始,apt-key 被弃用,并将在未来的版本中完全移除。因此&#…...
69.在 Vue 3 中使用 OpenLayers 拖拽实现放大区域的效果(DragPan)
引言 在现代 Web 开发中,地图功能已经成为许多应用的重要组成部分。OpenLayers 是一个功能强大的开源地图库,支持多种地图源和交互操作。Vue 3 是一个流行的前端框架,以其响应式数据和组件化开发著称。本文将介绍如何在 Vue 3 中集成 OpenLa…...
77,【1】.[CISCN2019 华东南赛区]Web4
有句英文,看看什么意思 好像也可以不看 进入靶场 点击蓝色字体 我勒个豆,百度哇 所以重点应该在url上,属于任意文件读取类型 接下来该判断框架了 常见的web框架如下 一,Python 框架 1.Flask URL 示例 1:http://…...
手撕B-树
一、概述 1.历史 B树(B-Tree)结构是一种高效存储和查询数据的方法,它的历史可以追溯到1970年代早期。B树的发明人Rudolf Bayer和Edward M. McCreight分别发表了一篇论文介绍了B树。这篇论文是1972年发表于《ACM Transactions on Database S…...
SQL 指南
SQL 指南 引言 SQL(Structured Query Language,结构化查询语言)是一种用于管理关系数据库系统的标准计算机语言。自1970年代问世以来,SQL已经成为了数据库管理和数据操作的事实标准。本文旨在为初学者和有经验的数据库用户提供一个全面的SQL指南,涵盖SQL的基础知识、高级…...
一文简单回顾复习Java基础概念
还是和往常一样,我以提问的方式回顾复习,今天回顾下Java小白入门应该知道的一些基础知识 Java语言有哪些特点呢? Java语言的特点有: 面向对象,主要是封装、继承、多态;平台无关性,“一次编写…...
Git上传了秘钥如何彻底修改包括历史记录【从安装到实战详细版】
使用 BFG Repo-Cleaner 清除 Git 仓库中的敏感信息 1. 背景介绍 在使用 Git 进行版本控制时,有时会不小心将敏感信息(如 API 密钥、密码等)提交到仓库中。即使后续删除,这些信息仍然存在于 Git 的历史记录中。本文将介绍如何使用…...
GCC之编译(8)AR打包命令
GCC之(8)AR二进制打包命令 Author: Once Day Date: 2025年1月23日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-C…...
Linux二进制部署K8s集群的平滑升级教程
一、升级前的准备工作 备份集群配置和数据 备份/etc/kubernetes/目录,其中包含Kubernetes集群的配置文件。 备份/var/lib/etcd/目录,其中存储了etcd数据库的数据。 使用etcdctl工具备份etcd数据: bash复制 ETCDCTL_API3 etcdctl snapshot s…...
2.1.3 第一个工程,点灯!
新建工程 点击菜单栏左上角,新建工程或者选择“文件”-“新建工程”,选择工程类型“标准工程”选择设备类型和编程语言,并指定工程文件名及保存路径,如下图所示: 选择工程类型为“标准工程” 选择主模块机型&#x…...
图像处理算法研究的程序框架
目录 1 程序框架简介 2 C#图像读取、显示、保存模块 3 C动态库图像算法模块 4 C#调用C动态库 5 演示Demo 5.1 开发环境 5.2 功能介绍 5.3 下载地址 参考 1 程序框架简介 一个图像处理算法研究的常用程序逻辑框架,如下图所示 在该框架中,将图像处…...
计算机工程:解锁未来科技之门!
计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展,计算机技术已经深深渗透到我们生活的方方面面,从医疗、金融到教育,无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业,计算机技术的应用尤为突出。比如&a…...
Linux初识——基本指令(2)
本文将继续从上篇末尾讲起,讲解我们剩下的基本指令 一、剩余的基本指令 1、mv mv指令是move(移动)的缩写,其功能为:1.剪切文件、目录。2.重命名 先演示下重命名,假设我想把当前目录下的di34改成dir5 那…...
单片机-STM32 WIFI模块--ESP8266 (十二)
1.WIFI模块--ESP8266 名字由来: Wi-Fi这个术语被人们普遍误以为是指无线保真(Wireless Fidelity),并且即便是Wi-Fi联盟本身也经常在新闻稿和文件中使用“Wireless Fidelity”这个词,Wi-Fi还出现在ITAA的一个论文中。…...
[C++技能提升]类注册
最近在做AI信息在各个平台流转的框架设计,想要设计一种可以灵活扩展、不改变原有代码的框架,了解到了类注册。 具体需求是这样的:AI算法在客户本地电脑和云端都有部署,原先AI在这两个平台下的输出格式并不统一,且每个…...
OpenHarmony 5.0.2 Release来了!
版本概述 OpenHarmony 5.0.2 Release版本对标准系统的能力进行持续完善,以快速迭代的方式推出API 14,相比5.0.1 Release版本,重点做出了如下特性新增或增强: 进一步增强ArkUI、图形图像的能力,提供更多组件的高级属性…...
80,【4】BUUCTF WEB [SUCTF 2018]MultiSQL
53,【3】BUUCTF WEB october 2019 Twice SQLinjection-CSDN博客 上面这个链接是我第一次接触二次注入 这道题也涉及了 对二次注入不熟悉的可以看看 BUUCTF出了点问题,打不开,以下面这两篇wp作为学习对象 [SUCTF 2018]MultiSQL-CSDN博客 …...
NR_shell运行流程简析
nr_shell 是一套开源 shell 框架,基于框架可创建终端交互功能。 为了记录终端输入指令,以及进行解析处理,nr_shell 提供了一套 cmd 结构体,具体如下:typedef struct static_cmd_function_struct {char cmd[NR_SHELL_CM…...
Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置
Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置 1.Prometheus部署1.2.Prometheus修改默认端口 2.grafana可视化页面部署3.alertmanager部署4.监控配置4.1.主机监控node-exporter4.2.监控mysql数据库mysqld_exporter4.3.监控mongod数据库mongodb_expo…...
问题排查 - TC397 CORE2 50MS/100MS任务不运行
1、问题描述 CORE2 的任务运行次数的计数值OsTask_100ms_Core2 - task_cnt[12]、OsTask_50ms_Core2 - task_cnt[16]不在累加,但是其他任务OsAlarm_1ms_Core2、OsAlarm_5ms_Core2、OsAlarm_10ms_Core2、OsAlarm_20ms_Core2 任务计数值累加正常。 如果是任务栈溢出&a…...
Spring FatJar写文件到RCE分析
背景 现在生产环境部署 spring boot 项目一般都是将其打包成一个 FatJar,即把所有依赖的第三方 jar 也打包进自身的 app.jar 中,最后以 java -jar app.jar 形式来运行整个项目。 运行时项目的 classpath 包括 app.jar 中的 BOOT-INF/classes 目录和 BO…...
百度APP iOS端磁盘优化实践(上)
01 概览 在APP的开发中,磁盘管理已成为不可忽视的部分。随着功能的复杂化和数据量的快速增长,如何高效管理磁盘空间直接关系到用户体验和APP性能。本文将结合磁盘管理的实践经验,详细介绍iOS沙盒环境下的文件存储规范,探讨业务缓…...
蓝桥杯之c++入门(一)【第一个c++程序】
目录 前言一、第⼀个C程序1.1 基础程序1.2 main函数1.3 字符串1.4 头文件1.5 cin 和 cout 初识1.6 名字空间1.7 注释 二、四道简单习题(点击跳转链接)练习1:Hello,World!练习2:打印飞机练习3:第⼆个整数练习4ÿ…...
14-6-1C++STL的list
(一)list容器的基本概念 list容器简介: 1.list是一个双向链表容器,可高效地进行插入删除元素 2.list不可以随机存取元素,所以不支持at.(pos)函数与[ ]操作符 (二)list容器头部和尾部的操作 list对象的默…...
【AI论文】Sigma:对查询、键和值进行差分缩放,以实现高效语言模型
摘要:我们推出了Sigma,这是一个专为系统领域设计的高效大型语言模型,其独特之处在于采用了包括DiffQKV注意力机制在内的新型架构,并在我们精心收集的系统领域数据上进行了预训练。DiffQKV注意力机制通过根据查询(Q&…...
