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

【C++】分书问题:深入解析、回溯法高级应用与理论拓展


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
  • 💯思路与算法
    • 回溯法理论基础
  • 💯代码实现与解析
    • 完整代码
    • 代码关键步骤解析
  • 💯时间复杂度与空间复杂度分析
  • 💯理论拓展:回溯法的高级应用
  • 💯小结


在这里插入图片描述


💯前言

  • 分书问题是回溯法在组合优化与约束满足问题中的一个典型应用。尽管问题规模较小,但背后反映出的搜索空间生成约束条件裁剪方案排序等问题,恰恰是算法设计中值得深思的核心内容。本篇文章将面向有较高编程基础的读者,深入解析题目本质,提供详细的代码实现与理论优化,同时对回溯法的应用进行拓展探讨,展示其在算法研究与工程实践中的广泛适用性。此外,我们还会对回溯法的特点复杂度分析其在更复杂问题中的推广进行深入讨论,帮助读者系统掌握这一经典算法的应用与演变。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

问题背景
设有 N N N 本书与 N N N 个人,每个人对书籍的喜好用一个二维矩阵 l i k e [ i ] [ j ] like[i][j] like[i][j] 表示:

  • l i k e [ i ] [ j ] = 1 like[i][j] = 1 like[i][j]=1,表示第 i i i 个人喜欢第 j j j 本书;
  • l i k e [ i ] [ j ] = 0 like[i][j] = 0 like[i][j]=0,表示第 i i i 个人不喜欢第 j j j 本书。

问题目标
设计一个程序,输出所有满足以下条件的分书方案:

  1. 每本书分配给一个人,且每个人最多得到一本书;
  2. 分配方案中,所有人都必须喜欢自己分到的书。

输入格式:

  • 1 1 1 行:整数 N N N 1 ≤ N ≤ 5 1 \leq N \leq 5 1N5);
  • 接下来的 N N N 行:矩阵 l i k e like like,每行包含 N N N 个整数 0 0 0 1 1 1

输出格式:

  • 每行输出一种合法的分书方案。
  • 输出按字典序排序,方案格式为:第 1 ∼ N 1 \sim N 1N 本书依次分配给的人的编号。

输入示例:

5
0 1 1 0 0
1 1 0 0 1
0 1 1 0 1
0 0 0 1 0
0 1 0 0 1

输出示例:

2 3 1 4 5
2 5 1 4 3

💯思路与算法

本题实质是一个排列组合搜索问题,涉及约束条件过滤,所有的可行方案需按照字典序输出。因此,解题的核心在于:

  1. 搜索空间构建:所有书的分配方案。
  2. 约束条件:分配给某人的书,必须是他喜欢的书。
  3. 去重与排序:利用回溯法,按字典序遍历所有合法方案。

回溯法理论基础

回溯法是深度优先搜索(DFS)的一种形式,适用于组合问题、排列问题以及约束满足问题。其基本过程包括:

  1. 状态选择:逐步选择合法的解分配到当前状态。
  2. 约束剪枝:对于不满足条件的状态,及时停止搜索。
  3. 回溯撤销:当搜索结束或无解时,撤销当前状态,回到上一步尝试其他选择。

本题中,书本与人存在一一映射关系,状态空间的规模为 N ! N! N!(阶乘)。借助回溯法,可以对 N ! N! N! 的状态进行搜索,同时通过约束 l i k e [ i ] [ j ] like[i][j] like[i][j] 进行剪枝,大幅缩小搜索空间。此外,回溯的每一步都需要确保:当前分配的状态合法,且不会影响后续的决策。


💯代码实现与解析


完整代码

#include <bits/stdc++.h>
using namespace std;int N;
int like[6][6];        // 1-based 矩阵,表示喜好关系
bool used[6];          // 标记某人是否已分配书
int assign[6];         // 每本书的分配结果
vector<vector<int>> solutions;  // 存储所有合法方案// 回溯函数
void backtrack(int book) {if (book > N) {  // 所有书已分配solutions.emplace_back(assign + 1, assign + N + 1);return;}for (int person = 1; person <= N; person++) {if (!used[person] && like[person][book]) {  // 当前人喜欢这本书且未分配used[person] = true;assign[book] = person;backtrack(book + 1);used[person] = false;  // 撤销选择,回溯}}
}int main() {cin >> N;for (int i = 1; i <= N; i++) {for (int j = 1; j <= N; j++) {cin >> like[i][j];}}backtrack(1);  // 从第一本书开始分配sort(solutions.begin(), solutions.end());  // 对所有方案按字典序排序for (const auto &sol : solutions) {for (int i = 0; i < N; i++) {cout << sol[i] << (i == N - 1 ? '\n' : ' ');}}return 0;
}

在这里插入图片描述


代码关键步骤解析

  1. 搜索空间的遍历:通过回溯法逐步尝试所有可能的分配方案。
  2. 约束过滤:利用 like 矩阵剪枝,排除不合法的分配。
  3. 状态回溯:递归结束后,恢复当前状态,继续尝试其他方案。
  4. 结果排序:所有方案按字典序输出,满足题目要求。

💯时间复杂度与空间复杂度分析

  • 搜索空间规模: N ! N! N!(最大 120)。
  • 剪枝操作:有效减少无效分配,优化搜索效率。
  • 排序复杂度: O ( M log ⁡ M ) O(M \log M) O(MlogM),其中 M M M 是合法方案的数量。

整体时间复杂度为:
O ( N ! + M log ⁡ M ) O(N! + M \log M) O(N!+MlogM)
空间复杂度为: O ( N ) O(N) O(N),用于存储当前状态和递归栈。


💯理论拓展:回溯法的高级应用

回溯法在约束满足问题(CSP)中扮演核心角色,例如:

  1. N 皇后问题:将 N 个皇后放置在 N × N N \times N N×N 棋盘上,确保任意两个皇后不互相攻击。
  2. 数独求解:填充数独表格,满足所有行、列和子区域的约束。
  3. 图的着色问题:为图的顶点分配颜色,确保相邻顶点颜色不同。

在实际应用中,回溯法还可以结合启发式搜索与动态约束传播,进一步提升求解效率。


💯小结

  • 在这里插入图片描述
    分书问题通过回溯法求解,展现了搜索空间构建约束剪枝方案排序的有机结合。本篇文章不仅详细解析了问题的解决思路与代码实现,还拓展讨论了回溯法在 CSP 问题中的应用与复杂度分析。通过掌握回溯法这一基础算法,读者可以在更多复杂问题中找到高效而系统的解决方案,进一步推动算法设计与实践的深入探索。

在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

相关文章:

【C++】分书问题:深入解析、回溯法高级应用与理论拓展

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;思路与算法回溯法理论基础 &#x1f4af;代码实现与解析完整代码代码关键步骤解析 &#x1f4af;时间复杂度与空间复杂度分析&#x1f4af;理论拓展&…...

java开发入门学习五-流程控制

流程控制语句 if&#xff0c; if...else&#xff0c; if..else if..else 与前端相同 略 switch case 与前端不同的是case不能使用表达式&#xff0c;使用表达式会报错 class TestSwitch {public static void main(String[] args) {// switch 表达式只能是特定的数据类型…...

【FFmpeg 教程 一】截图

本章使用 ffmpeg 实现观影中经常会用到的功能&#xff0c;截图。 以下给出两种方式。 课程需具备的基础能力&#xff1a;Python 1. 使用 subprocess 调用 FFmpeg 命令 import subprocess def extract_frame(video_path, output_image_path, timestamp"00:00:05")&qu…...

北邮,成电计算机考研怎么选?

#总结结论&#xff1a; 基于当前提供的24考研复录数据&#xff0c;从报考性价比角度&#xff0c;建议25考研的同学优先选择北邮计算机学硕。主要原因是:相比成电&#xff0c;北邮计算机学硕的目标分数更低&#xff0c;录取率更高&#xff0c;而且北邮的地理位置优势明显。对于…...

深入了解京东API接口:如何高效获取商品详情与SKU信息

在当今数字化时代&#xff0c;电商平台的数据接口成为了连接商家与消费者的桥梁。京东作为国内领先的电商平台&#xff0c;其API接口为开发者提供了丰富的商品信息获取途径。本文将深入探讨如何使用京东API接口高效获取商品详情与SKU信息&#xff0c;并附上简短而实用的代码示例…...

C++常见内存泄漏案例分析以及解决方案

C 常见内存泄漏案例分析以及解决方案 1. 分配与释放不匹配 在动态内存管理中&#xff0c;使用new操作符分配的内存必须通过delete操作符显式释放。若未遵循这一规则&#xff0c;将导致内存泄漏。例如&#xff1a; int *p new int; p new int; // 错误&#xff1a;未释放先…...

[LeetCode-Python版]206. 反转链表(迭代+递归两种解法)

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&#xff1…...

70 mysql 中事务的隔离级别

前言 mysql 隔离级别有四种 未提交读, 已提交读, 可重复度, 序列化执行 然后不同的隔离级别存在不同的问题 未提交读存在 脏读, 不可重复度, 幻觉读 等问题 已提交读存在 不可重复度, 幻觉读 等问题 可重复读存在 幻觉读 等问题 序列化执行 没有以上问题 然后 我们这里…...

C语言二叉树

1.思维导图 树 二叉树 2.将链式队列重新实现一遍 linkqueue.c #include"linkqueue.h" linkqueuePtr create() {linkqueuePtr L(linkqueuePtr)malloc(sizeof(linkqueue));if(NULLL){printf("队列创建失败\n");return NULL;}L->head(nodePtr)malloc(si…...

智能工厂的设计软件 三种处理单元(NPU/GPU/CPU)及其在深度学习框架中的作用 之1

本文要点 深度学习&#xff1a;认知系统架构的处理层 在认知系统架构的设计和代码实现上 需要考虑多个层次&#xff0c;包括感知层、处理层、决策层和执行层。其中 深度学习主要用来解决处理层上的认知问题。 感知层&#xff1a;负责收集外部环境的信息。 处理层&#xff1a;…...

iOS swift开发系列--如何给swiftui内容视图添加背景图片显示

我需要在swiftui项目中显示背景图&#xff0c;有两种方式&#xff0c;一种是把图片拖入asset资源中&#xff0c;另外一种是直接把图片放在源码目录下。采用第一种方式&#xff0c;直接把图片拖到资源目录&#xff0c;但是swiftui项目没有弹出&#xff0c; “Copy items if need…...

jmeter后端监视器

一、概述 JMeter 后端监听器(Backend Listener)是 JMeter 提供的一个功能强大的插件,用于将测试执行期间收集的性能数据发送到外部系统进行监控和分析。通过后端监听器,您可以实时地将 JMeter 测试执行期间收集的数据发送到外部系统,如图形化展示、数据库、数据分析工具等…...

服务器数据恢复—RAIDZ离线硬盘数超过热备盘数导致阵列崩溃的数据恢复案例

服务器存储数据恢复环境&#xff1a; ZFS Storage 7320存储阵列中有32块硬盘。32块硬盘分为4组&#xff0c;每组8块硬盘&#xff0c;共组建了3组RAIDZ&#xff0c;每组raid都配置了热备盘。 服务器存储故障&#xff1a; 服务器存储运行过程中突然崩溃&#xff0c;排除人为误操…...

面试题整理4----lvs,nginx,haproxy区别和使用场景

LVS、Nginx、HAProxy&#xff1a;区别与使用场景 1. LVS&#xff08;Linux Virtual Server&#xff09;1.1 介绍1.2 特点1.3 使用场景 2. Nginx2.1 介绍2.2 特点2.3 使用场景 3. HAProxy3.1 介绍3.2 特点3.3 使用场景 4. 总结对比 在构建高可用、高性能的网络服务时&#xff0c…...

iOS - 超好用的隐私清单修复脚本(持续更新)

文章目录 前言开发环境项目地址下载安装隐私访问报告隐私清单模板最后 前言 在早些时候&#xff0c;提交应用到App Store审核&#xff0c;大家应该都收到过类似这样的邮件&#xff1a; Although submission for App Store review was successful, you may want to correct th…...

html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>

1.代码 <ul><li>电话&#xff1a;<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱&#xff1a;<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱&#xff1a;<a hre…...

clickhouse-副本和分片

1、副本 1.1、概述 集群是副本和分片的基础&#xff0c;它将ClickHouse的服务拓扑由单节点延伸到多个节点&#xff0c;但它并不像Hadoop生态的某些系统那样&#xff0c;要求所有节点组成一个单一的大集群。ClickHouse的集群配置非常灵活&#xff0c;用户既可以将所有节点组成…...

2009 ~ 2019 年 408【计算机网络】大题解析

2009 年 路由算法&#xff08;9’&#xff09; 讲解视频推荐&#xff1a;【BOK408真题讲解-2009年&#xff08;催更就退网版&#xff09;】 某网络拓扑如下图所示&#xff0c;路由器 R1 通过接口 E1 、E2 分别连接局域网 1 、局域网 2 &#xff0c;通过接口 L0 连接路由器 R2 &…...

vue2使用render,js中写html

1、js部分table.js export default {name: "dadeT",data() {return {dades: 6666};},render(h) {return h(div, [h(span, 组件数据&#xff1a;${this.dades}), // 利用data里的dades数据&#xff0c;展示在页面上h(span, 89855545)]);} };2、vue部分 <templat…...

如何有效划分服务器磁盘空间?具体的步骤和流程

有效划分服务器磁盘空间对于提升系统性能、管理方便性和数据安全性至关重要。合理的磁盘分区不仅有助于提高服务器的运行效率&#xff0c;还能在数据恢复、系统故障修复和存储管理方面提供更高的灵活性。以下是如何有效划分服务器磁盘空间的几个关键步骤和注意事项。 磁盘分区的…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...