当前位置: 首页 > news >正文

【算法】递归型枚举与回溯剪枝初识

递归型枚举与回溯剪枝初识

  • 1.枚举子集
  • 2.组合型枚举
  • 3.枚举排列
  • 4.全排列问题

  1. 什么是搜索?搜索,是一种枚举,通过穷举所有的情况来找到最优解,或者统计合法解的个数。因此,搜索有时候也叫作暴搜。搜索一般分为深度优先搜索(DFS)与宽度优先搜索(BFS)。
  2. 深度优先遍历 vs 深度优先搜索,宽度优先遍历 vs 宽度优先搜索。遍历是形式,搜索是目的。不过,在一般情况下,我们不会去纠结概念的差异,两者可以等同。
  3. 回溯与剪枝
  • 回溯:当在搜索的过程中,遇到走不通或者走到底的情况时,就回头。
  • 剪枝:在搜索过程中,剪掉重复出现或者不是最优解的分。

递归型枚举与回溯剪枝初识:

  • 画决策树
  • 根据决策树写递归

搜索的本质:对决策树进行一次遍历,直到将所有的情况搜集到为止。

1.枚举子集

B3622 枚举子集(递归实现指数型枚举)

在这里插入图片描述

解法:深搜

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

在这里插入图片描述

设计递归函数:

  1. 重复子问题:针对某一位,「选」或者「不选」。因为最终结果要按照「字典序」输出,我们可以「先考虑不选」,然后「再考虑选」。
  2. 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#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 个位置应该选哪个数,我们可以画出如下决策树:

在这里插入图片描述

设计递归函数:

  1. 重复子问题:当前这一位,应该放哪个数上去。因为这是一个「组合」问题,不涉及排列,所以我们当前位置开始放的数,应该是「上次决策的数的下一位」。
  2. 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#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. 重复子问题:考虑这一位要放上什么数。因为是「排列」问题,所以我们直接从 1 开始枚举要放的数。
  2. 剪枝:在这一条路径中,我们「不能选择之前已经选择过的数」,需要用到辅助数组
  3. 实现方式参考代码和注释,结合「决策树」一起看会很清晰。
#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.全排列问题 什么是搜索&#xff1f;搜索&#xff0c;是一种枚举&#xff0c;通过穷举所有的情况来找到最优解&#xff0c;或者统计合法解的个数。因此&#xff0c;搜索有时候也叫作暴搜。搜索一般分为深度优先搜索…...

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整 0 前言 之前文章添加了一个自定义的模块&#xff0c;本篇文章在之前的自定义模块中&#xff0c;添加两个自定义参数 使用QGC显示出来&#xff0c;并通过QGC调整参数值&#xff0c;代码实现参数更新 新增的参…...

《CPython Internals》阅读笔记:p356-p359

《CPython Internals》学习第 19天&#xff0c;p356-p359 总结&#xff0c;总计 4 页。 一、技术总结 1.benchmark suite The benchmark suite is the tool to use when comparing the complete performance of Python. The Python Benchmark suite is a collection of Pyth…...

Linux--权限

Linux系统的权限管理是保障系统安全的重要机制&#xff0c;以下详细讲解权限相关概念及操作指令&#xff1a; 一、基础权限机制 1. 权限的三元组&#xff0c;读&#xff08;r&#xff09;、写&#xff08;w&#xff09;、执行&#xff08;x&#xff09; 每个文件或目录有三组…...

java后端之登录认证

基础登录功能&#xff1a;根据提供的用户名和密码判断是否存在于数据库 LoginController.java RestController Slf4j public class LoginController {Autowiredprivate UserService userService;PostMapping("/login")public Result login(RequestBody User user) {…...

【矩阵二分】力扣378. 有序矩阵中第 K 小的元素

给你一个 n x n 矩阵 matrix &#xff0c;其中每行和每列元素均按升序排序&#xff0c;找到矩阵中第 k 小的元素。 请注意&#xff0c;它是 排序后 的第 k 小元素&#xff0c;而不是第 k 个 不同 的元素。 你必须找到一个内存复杂度优于 O(n2) 的解决方案。 示例 1&#xff1…...

C语言-构造数据类型

1、构造数据类型 结构体、共用体、枚举。 2、结构体 1、结构体的定义 结构体是一个自定义的复合数据类型&#xff0c;它允许将不同类型的数据组合在一起。 struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;数据类型4 成员变量4; } 2、结构体变…...

鸿蒙next 自定义日历组件

效果图预览 20250124-113957 使用说明 1.选择日期左右箭头&#xff0c;实现每月日历切换&#xff0c;示例中超出当前月份&#xff0c;禁止进入下一月&#xff0c;可在代码更改 2.日历中显示当前选择的日期&#xff0c;选中的日期颜色可自定义 3.日历中可展示历史记录作为数据…...

【express-generator】08-路由重定向

前言 通过前面两篇文章的讲解&#xff0c;我们已经介绍完第二阶段的前两点&#xff0c;本篇介绍第三点&#xff1a;路由重定向。 1. 路由重定向概述 路由重定向是指在服务器端将客户端的请求从一个 URL 重定向到另一个 URL 的过程。这通常通过 HTTP 状态码&#xff08;如 30…...

搭建Spring Boot开发环境

JDK&#xff08;1.8及以上版本&#xff09; Apache Maven 3.6.0 修改settings.xml 设置本地仓库位置 <localRepository>D:/repository</localRepository> 设置远程仓库镜像 <mirror><id>alimaven</id><name>aliyun maven</name&…...

Spatial Group-wise Enhance (SGE) module

来源&#xff1a; [1905.09646] Spatial Group-wise Enhance: Improving Semantic Feature Learning in Convolutional Networks 相关工作&#xff1a; #GroupedFeatures #AttentionModels 创新点&#xff1a; 贡献&#xff1a; 提出了一种轻量级的SGE模块&#xff0c;能够…...

二叉搜索树中的搜索(力扣700)

首先介绍一下什么是二叉搜索树。 二叉搜索树是一个有序树&#xff1a; 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b;若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点的值&#xff1b;它的左、右子树也分别为二叉…...

记录让cursor帮我给ruoyi-vue后台管理项目整合mybatis-plus

自己整合过程中会出现 work.web.exception.GlobalExceptionHandler :100 | 请求地址/admin/device/install/detail/1,发生未知异常. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.fire.mapper.DeviceInstallMapper.selectById at o…...

【可实战】Linux 系统扫盲、 Shell扫盲(如何写一个简单的shell脚本)

一、Linux系统扫盲 1.Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议 2.Linux 的发行版说简单点就是将 Linux 内核与应用软件做一个打包。 目前市面上较知名的发行版有&#xff1a;Ubuntu、RedHat、CentOS、Debian、Fedora、SuSE、OpenSUSE、Arch Linux、SolusOS 等…...

sqlzoo答案4:SELECT within SELECT Tutorial

sql练习&#xff1a;SELECT within SELECT Tutorial - SQLZoo world表&#xff1a; namecontinentareapopulationgdpAfghanistanAsia6522302550010020343000000AlbaniaEurope28748283174112960000000AlgeriaAfrica238174137100000188681000000AndorraEurope46878115371200000…...

【fly-iot飞凡物联】(20):2025年总体规划,把物联网整套技术方案和实现并落地,完成项目开发和课程录制。

前言 fly-iot飞凡物联专栏&#xff1a; https://blog.csdn.net/freewebsys/category_12219758.html 1&#xff0c;开源项目地址进行项目开发 https://gitee.com/fly-iot/fly-iot-platform 完成项目开发&#xff0c;接口开发。 把相关内容总结成文档&#xff0c;并录制课程。…...

Lucene常用的字段类型lucene检索打分原理

在 Apache Lucene 中&#xff0c;Field 类是文档中存储数据的基础。不同类型的 Field 用于存储不同类型的数据&#xff08;如文本、数字、二进制数据等&#xff09;。以下是一些常用的 Field 类型及其底层存储结构&#xff1a; TextField&#xff1a; 用途&#xff1a;用于存储…...

适用于IntelliJ IDEA 2024.1.2部署Tomcat的完整方法,以及笔者踩的坑,避免高血压,保姆级教程

Tips:创建部署Tomcat直接跳转到四 一、软件准备 笔者用的是IntelliJ IDEA 2024.1.2和Tomcat 8.5。之前我使用的是Tomcat 10&#xff0c;但遇到了许多问题。其中一个主要问题是需要使用高于1.8版本的JDK&#xff0c;为此我下载了新的JDK版本&#xff0c;但这又引发了更多的兼容…...

XSS靶场通关详解

前言 这里作者采用phpstudy部署的xss-lab靶场&#xff0c;配置如下&#xff1a; 第一关 进入靶场后寻找页面的传参处&#xff0c;发现url中的name参数传了test给页面&#xff0c;可以在此处进行尝试xss 成功弹窗&#xff01; payload&#xff1a; <script>alert(1)<…...

Excel 技巧15 - 在Excel中抠图头像,换背景色(★★)

本文讲了如何在Excel中抠图头像&#xff0c;换背景色。 1&#xff0c;如何在Excel中抠图头像&#xff0c;换背景色 大家都知道在PS中可以很容易抠图头像&#xff0c;换背景色&#xff0c;其实Excel中也可以抠简单的图&#xff0c;换背景色。 ※所用头像图片为百度搜索&#x…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...