【废物研究生零基础刷算法】DFS与递归(一)典型题型

文章目录

  • 跳台阶
  • 递归实现指数级枚举
  • 递归实现排列型枚举
    • 上面两题总结
  • 递归实现组合型枚举
  • P1036选数

跳台阶

在这里插入图片描述
思路:

  • 如果 n = 1,只有一种走法(走 1 级)。
  • 如果 n = 2,有两种走法(1+1 或 2)。
  • 对于 n > 2,到达第 n 级的方法可以分解为:
  • 从第 n-1 级走 1 级上来,方案数为 f(n-1);从第 n-2 级走 2 级上来,方案数为 f(n-2)。
  • 因此,总方案数 f(n) = f(n-1) + f(n-2)。
def Fibonacci(x):if x==1: return 1if x==2: return 2return Fibonacci(x-1)+Fibonacci(x-2)n = int(input())
print(Fibonacci(n))

递归实现指数级枚举

在这里插入图片描述
思路:

  1. 顺序:从1~n依次考虑每个数选/不选,可能的结果是2^n
  2. 使用长度为n的数组st来记录每个数是选还是不选:0(不确定选不选)、1(选择)、2(不选择)
  3. 传入的参数x代表选择的位置
N = 20  # 数据范围最大 n ≤ 15,定义一个稍大的常量
st = [0] * N  # 初始化 st 数组,长度固定,所有元素为 0
n = int(input())  # 输入 ndef dfs(x):if x > n:  # 当 x 超过 n,说明所有数都考虑完了,输出方案selected = []  # 存储被选择的数字for i in range(1, n + 1):  # 检查 1 到 n 的状态if st[i] == 1:  # 如果选择这个数selected.append(i)if not selected:  # 如果没有选择任何数,输出空行print(" ")else:print(" ".join(map(str, selected)))  # 输出选择的数字,用空格分隔.map(str, selected) 的作用是将 selected 列表中的每个元素(数字)转换为字符串。return# 不选择当前数 xst[x] = 2dfs(x + 1)st[x] = 0  # 回溯,恢复状态为未考虑# 选择当前数 xst[x] = 1dfs(x + 1)st[x] = 0  # 回溯,恢复状态为未考虑dfs(1)  # 从 1 开始

递归实现排列型枚举

在这里插入图片描述
思路:

  1. 考虑每个位置能存放的数
  2. 使用布尔类型的数组st表示当前存放的状态,True表示有该数,False表示没有该数
N = 20  # 常量,稍大于 n 的最大值 15
n = int(input())  # 输入 n
arr = [0] * N  # 存储当前排列的数组
st = [False] * N  # 标记数字是否使用,0 到 n-1 表示数字 1 到 ndef dfs(x):if x > n:  # 当 x 超过 n,说明排列已填满,输出结果result = ""for i in range(1, n + 1):  # 输出 arr[1] 到 arr[n]result += f"{arr[i]:5d}"  # 每个数字占 5 个字符宽度print(result)returnfor i in range(1, n + 1):  # 枚举 1 到 n 的数字if not st[i]:  # 如果数字 i 还未使用st[i] = True  # 标记为已使用arr[x] = i  # 将 i 放入当前位置dfs(x + 1)  # 递归填下一个位置st[i] = False  # 回溯,恢复未使用状态arr[x] = 0  # 回溯,清空当前位置dfs(1)  # 从位置 1 开始填

上面两题总结

为什么回溯处理方式不同?

  1. 子集问题(指数型枚举)为什么不用for循环?
  • 决策方式:对于每个数字 x,只有“选”或“不选”两种固定选择。
  • 状态独立:选择 x 不会影响其他数字的可用性,因此不需要遍历所有可能选项,只需直接指定状态(st[x] = 1 或 2)。
  • 回溯逻辑:
    • 每次递归只处理一个数字的状态。
    • 直接设置 st[x],递归后恢复为 0,不需要额外的循环来尝试其他值。
  • 本质:这是一个二分支问题(选或不选),每个位置的决策是固定的二选一。
  1. 全排列问题为什么用 for 循环?
  • 决策方式:对于每个位置 x,需要从剩余未使用的数字中选择一个,而不是简单的二选一。
  • 状态依赖:某个数字 i 被选后,后续位置不能再用它,因此需要用 st 检查哪些数字可用。
  • 回溯逻辑:
    • 用 for i in range(1, n + 1) 遍历所有数字,检查 st[i] 是否为 False(未使用)。
    • 每次尝试一个可用的 i,标记为已用(st[i] = True),填入 arr[x],递归后回溯。
  • 本质:这是一个多分支问题(从 n 个数字中选一个),每个位置需要动态枚举当前可用的选项。

递归实现组合型枚举

在这里插入图片描述

N = 30
n, r = map(int, input().split())  # 一行输入 n 和 r
st = [False] * N  # 标记数字是否使用
arr = [0] * N  # 存储当前组合def dfs(x, start):if x > r:  # 选满 r 个数时输出result = ""for i in range(1, r + 1):  # 输出 arr[1] 到 arr[r]result += f"{arr[i]:3d}"  # 每个数字占 3 个字符宽度print(result)returnfor i in range(start, n + 1):  # 从 start 到 n 枚举if not st[i]:  # 如果 i 未使用st[i] = True  # 标记已使用arr[x] = i  # 放入当前位置dfs(x + 1, i + 1)  # 递归,下一位置从 i+1 开始st[i] = False  # 回溯arr[x] = 0  # 回溯dfs(1, 1)  # 从位置 1 开始,从数字 1 开始选

P1036选数

在这里插入图片描述

N = 30
n, k = map(int, input().split())
q = list(map(int, input().split()))  # 输入数组
st = [False] * N  # 标记是否使用
arr = [0] * N  # 存储当前组合
count = 0def is_prime(n):if n < 2:return Falsefor i in range(2, int(n ** 0.5) + 1):if n % i == 0:return Falsereturn Truedef dfs(x, start):global count  # 声明 count 为全局变量if x > k:  # 选满 k 个数sum_val = 0for i in range(1, k + 1):sum_val += arr[i]if is_prime(sum_val):count += 1returnfor i in range(start, n):  # 从 start 到 n-1 枚举数组索引if not st[i]:  # 如果 q[i] 未使用st[i] = Truearr[x] = q[i]  # 存入当前数字dfs(x + 1, i + 1)  # 下一位置,从 i+1 开始st[i] = Falsearr[x] = 0dfs(1, 0)  # 从位置 1 开始,从数组索引 0 开始
print(count)

在这里插入图片描述

为什么需要global?

  • 函数外定义 ≠ 自动可修改:
    • 在函数外定义 count = 0 只意味着它在全局作用域存在,可以被读取。
    • 但函数内的任何赋值(如 count += 1、count = 5)都会创建一个新的局部变量,除非用 global 声明。
  • 保护全局变量:
    • Python 这样设计是为了防止函数意外修改全局状态。如果你想修改,必须明确意图。

如何从索引为1开始存放?

# 读取输入并转换为整数列表
q = list(map(int, input().split()))# 在列表开头插入一个占位元素 0
q.insert(0, 0)# 打印结果
print(q)

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

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

相关文章

GCC 和 G++的基本使用

GCC 和 G 命令 GCC 和 G 命令GCC&#xff08;GNU C 编译器&#xff09;基本用法常用选项示例 G&#xff08;GNU C 编译器&#xff09;基本用法常用选项示例 GCC 与 G 的区别选择使用 GCC 还是 G C编译流程1. 预处理&#xff08;Preprocessing&#xff09;2. 编译&#xff08;Co…

HWUI 和 Skia

&#x1f4cc; HWUI 和 Skia 的关系 Skia 是 Android 的底层 2D 图形库&#xff0c;提供 CPU 和 GPU 渲染能力&#xff0c;支持 OpenGL、Vulkan、Metal 等后端。HWUI 是 Android UI 组件的 GPU 渲染引擎&#xff0c;主要用于 加速 View、动画、阴影等 UI 元素的绘制。HWUI 依赖…

编写第一个 C++ 程序 – Hello World 示例

“Hello World”程序是学习任何编程语言的第一步&#xff0c;也是您将学习的最直接的程序之一。它是用于演示编码过程如何工作的基本程序。您所要做的就是在输出屏幕上显示 “Hello World”。 C Hello World 程序 下面是在控制台屏幕上打印 “Hello World” 的 C 程序。 // …

【Python量化金融实战】-第1章:Python量化金融概述:1.1量化金融的定义与发展历程

本小节学习建议&#xff1a;掌握Python编程、统计学&#xff08;时间序列分析&#xff09;、金融学基础&#xff08;资产定价理论&#xff09;三者结合&#xff0c;是进入量化领域的核心路径。 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章目录 1.1 量化金…

docker部署GPU环境

使用 Docker 部署 GPU 环境涉及到几个关键步骤,以下是详细步骤: 1. 安装 NVIDIA 驱动程序 确保你的系统已经安装了 NVIDIA GPU 驱动。这是使用 GPU 的前提条件。 2. 安装 Docker 和 nvidia-container-toolkit 首先,确保你已经安装了 Docker。然后,安装 NVIDIA Containe…

Pytorch实现之混合成员GAN训练自己的数据集

简介 简介:提出一种新的MMGAN架构,使用常见生成器分布的混合对每个数据分布进行建模。由于生成器在多个真实数据分布之间共享,高度共享的生成器(通过混合权重反映)捕获分布的公共方面,而非共享的生成器捕获独特方面。 论文题目:MIXED MEMBERSHIP GENERATIVE ADVERSARI…

matlab和java混合编程经验分享

最常用的就是可以查到再控制栏deploytool选择library complier打包&#xff0c;但是有问题就是比如果用了外部的求解器比如yalmip或者cplex的话用这个方法会找不到外部的求解器&#xff0c;网上找了很多&#xff0c;基本都大同小异。 后面分享一个亲测有效的打包方法&#xff0…

观成科技:海莲花“PerfSpyRAT”木马加密通信分析

1.概述 在2024年9月中旬至10月&#xff0c;东南亚APT组织“海莲花”通过GitHub发布开源安全工具项目&#xff0c;针对网络安全人员发起了定向攻击。通过对相关攻击活动进行分析&#xff0c;可以将其与一些海莲花的样本关联起来。这些样本的通信数据结构与海莲花此前使用的攻击…

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(一)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;一&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书DCRS:DCFW:DCWS:WAF: 第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&…

2月25(信息差)

&#x1f30d;四川省人民医院接入DeepSeek 将AI技术应用于看病全流程 &#x1f384;机器人新风口&#xff01;OpenAI押注公司 采用这种新材料 更轻盈耐磨&#xff01;尼龙概念股名单 ✨小米15 Ultra、小米SU7 Ultra定档2月27日 雷军宣布&#xff1a;向超高端进发 1.深夜王炸&…

全面汇总windows进程通信(三)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: RPC(远程过程调用,Remote Pr…

【栈与队列】二叉树最大宽度

文章目录 662. 二叉树最大宽度解题思路&#xff1a;队列 广度搜索 662. 二叉树最大宽度 662. 二叉树最大宽度 ​ 给你一棵二叉树的根节点 root &#xff0c;返回树的 最大宽度 。 ​ 树的 最大宽度 是所有层中最大的 宽度 。 ​ 每一层的 宽度 被定义为该层最左和最右的非…

大语言模型安全测试:WDTA 标准下的全面解读与实践展望

1.前言 在人工智能&#xff08;AI&#xff09;飞速发展的时代&#xff0c;大语言模型&#xff08;LLM&#xff09;凭借其强大的语言理解和生成能力&#xff0c;广泛应用于智能客服、智能写作、智能翻译等众多领域&#xff0c;深刻改变着人们的生活和工作方式。然而&#xff0c…

在WINDOWS系统使用CMake gui编译NLopt配合VSCode使用

1. 准备工作 安装CMake&#xff1a;从CMake官网下载并安装CMake。下载Nlopt源码&#xff1a;从Nlopt官网或GitHub仓库下载Nlopt源码。安装编译器&#xff1a;确保已安装Visual Studio或其他支持的编译器&#xff08;如MinGW&#xff09;。 2. 配置CMake 方式1 打开CMake GU…

【DeepSeek开源:会带来多大的影响】

DeepSeek 开源&#xff0c;震撼登场对云计算行业的冲击 巨头云厂商的新机遇 DeepSeek 开源后&#xff0c;为云计算行业带来了巨大的变革&#xff0c;尤其是为巨头云厂商创造了新的发展机遇。以阿里云为例&#xff0c;它作为云计算行业的领军者&#xff0c;与 DeepSeek 的合作…

C++ QT 6.6.1 QCustomPlot的导入及使用注意事项和示例 | 关于高版本QT使用QCustomPlot报错问题解决的办法

C QT 6.6.1 QCustomPlot的导入及使用注意事项和示例 | 关于高版本QT使用QCustomPlot报错问题解决的办法 记录一下 qmake .pro文件的配置 QT core gui printsupportgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compil…

深入理解 `Sinks.Empty<Void>` 和 `Mono<Void>`:如何触发完成信号并结合 WebSocket 示例

在响应式编程中&#xff0c;Sinks 是 Project Reactor 提供的一个强大工具&#xff0c;用于手动控制数据流的信号发射。Sinks.Empty<Void> 是一种特殊的 Sinks&#xff0c;它不发射任何数据&#xff0c;仅用于表示完成或错误信号。结合 Mono<Void>&#xff0c;它可…

LLM+多智能体协作:基于CrewAI与DeepSeek的邮件自动化实践

文章目录 引言理解 Flows&#xff08;工作流&#xff09;与 Crews&#xff08;协作组&#xff09;一、环境准备与工具安装1.1 Python环境搭建1.2 创建并激活虚拟环境1.3 安装核心依赖库&#xff08;crewai、litellm&#xff09; 二、本地DeepSeek R1大模型部署2.1 Ollama框架安…

Deepseek开源周,第二天:Deep EP

DeepSeek 开源的 DeepEP 项目是一个专为 MoE&#xff08;混合专家&#xff09;模型设计的开源通信库&#xff0c;旨在优化训练和推理效率。其对开发者的核心价值体现在以下方面&#xff1a; 1. 显著提升训练与推理性能 全连接通信优化 通过高效优化的 All-to-All 通信机制&…

分布式深度学习:探索无限可能

分布式深度学习:探索无限可能 大家好,我是Echo_Wish,一名专注于人工智能和Python的自媒体创作者。今天,我们将深入探讨分布式深度学习,这个技术不仅是AI发展的前沿,更是应对大规模数据和复杂模型的关键解决方案。随着数据量和模型复杂度的不断增加,传统的单机深度学习已…