【废物研究生零基础刷算法】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 1
    if x==2: return 2
    return 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())  # 输入 n

def 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
    
    # 不选择当前数 x
    st[x] = 2
    dfs(x + 1)
    st[x] = 0  # 回溯,恢复状态为未考虑
    
    # 选择当前数 x
    st[x] = 1
    dfs(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 到 n

def 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)
        return
    
    for 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)
        return
    
    for 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 = 0

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

def dfs(x, start):
    global count  # 声明 count 为全局变量
    if x > k:  # 选满 k 个数
        sum_val = 0
        for i in range(1, k + 1):
            sum_val += arr[i]
        if is_prime(sum_val):
            count += 1
        return
    
    for i in range(start, n):  # 从 start 到 n-1 枚举数组索引
        if not st[i]:  # 如果 q[i] 未使用
            st[i] = True
            arr[x] = q[i]  # 存入当前数字
            dfs(x + 1, i + 1)  # 下一位置,从 i+1 开始
            st[i] = False
            arr[x] = 0

dfs(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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java-01-源码篇-04集合-05-ConcurrentHashMap(1)

1.1 加载因子 加载因子&#xff08;Load Factor&#xff09;是用来决定什么时候需要扩容的一个参数。具体来说&#xff0c;加载因子 当前元素数量 / 桶的数量&#xff0c;当某个桶的元素个数超过了 桶的数量 加载因子 时&#xff0c;就会触发扩容。 我们都知道 ConcurrentHas…

AI赋能的未来城市:如何用智能化提升生活质量?

这会是我们憧憬的未来城市吗&#xff1f; 随着技术的不断进步和城市化进程的加速&#xff0c;现代城市面临着诸多挑战——交通拥堵、环境污染、能源消耗、人口老龄化等问题愈发突出。为了应对这些挑战&#xff0c;建设智慧城市已成为全球发展的重要趋势。在这一进程中&#xf…

DeepSeek各模型现有版本对比分析

文章目录 一、基础模型系列&#xff1a;V1 到 V3 的演进二、专用模型系列&#xff1a;推理与多模态三、版本选型与商业化趋势 DeepSeek作为最近特别火爆的模型&#xff0c;本文将对DeepSeek现有的主要版本进行对比分析,涵盖参数规模、训练数据、功能改进、应用场景和性能表现等…

【亲测有效】百度Ueditor富文本编辑器添加插入视频、视频不显示、和插入视频后二次编辑视频标签不显示,显示成img标签,二次保存视频被替换问题,解决方案

【亲测有效】项目使用百度Ueditor富文本编辑器上传视频相关操作问题 1.百度Ueditor富文本编辑器添加插入视频、视频不显示 2.百度Ueditor富文本编辑器插入视频后二次编辑视频标签不显示&#xff0c;在编辑器内显示成img标签&#xff0c;二次保存视频被替换问题 问题1&#xff1…

hot100_108. 将有序数组转换为二叉搜索树

hot100_108. 将有序数组转换为二叉搜索树 思路 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#…

RFID涉密载体柜:智能安全,全程守护,提供智能化的安全管控

行业背景 RFID智能载体柜&#xff08;DW-G101&#xff09;是一种便捷化的载体管控系统&#xff0c;它采用RFID技术实现信息化&#xff0c;可以大大提高载体管理的效率和准确性。 随着信息化的快速发展&#xff0c;涉密载体&#xff08;如文件、U盘、光盘等&#xff09;的管理…

【复习】计算机网络

网络模型 OSI 应用层&#xff1a;给应用程序提供统一的接口表示层&#xff1a;把数据转换成兼容另一个系统能识别的格式会话层&#xff1a;负责建立、管理、终止表示层实体之间的通信会话传输层&#xff1a;负责端到端的数据传输网络层&#xff1a;负责数据的路由、转发、分片…

多线程篇学习面试

多线程 1.乐观锁、CAS思想 java乐观锁机制&#xff1a; ​ 乐观锁体现的是悲观锁的反面。它是一种积极的思想&#xff0c;它总是认为数据是不会被修改的&#xff0c;所以是不会对数据上锁的。但是乐观锁在更新的时候会去判断数据是否被更新过。乐观锁的实现方案一般有两种&a…

Spring Boot 概要(官网文档解读)

Spring Boot 概述 Spring Boot 是一个高效构建 Spring 生产级应用的脚手架工具&#xff0c;它简化了基于 Spring 框架的开发过程。 Spring Boot 也是一个“构件组装门户”&#xff0c;何为构件组装门户呢&#xff1f;所谓的“构件组装门户”指的是一个对外提供的Web平台&#x…

计算机毕业设计SpringBoot+Vue.jst0甘肃非物质文化网站(源码+LW文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

匹配算法:向下就近原则,向下没有就向上

匹配算法&#xff1a;向下就近原则&#xff0c;向下没有就向上 实现方式一实现方式二总结 实现方式一 private static List<Integer> findMatches(List<Integer> sourceList, List<Integer> searchValues) {List<Integer> sortedList sourceList.stre…

ESP32S3:解决RWDT无法触发中断问题,二次开发者怎么才能使用内部RTC看门狗中断RWDT呢?

目录 基于ESP32S3:解决RWDT无法触发中断问题引言解决方案1. 查看报错日志2. 分析报错及一步一步找到解决方法3.小结我的源码基于ESP32S3:解决RWDT无法触发中断问题 引言 在嵌入式系统中,RWDT(看门狗定时器)是确保系统稳定性的重要组件。然而,在某些情况下,RWDT可能无法…

【GPU驱动】OpenGLES图形管线渲染机制

OpenGLES图形管线渲染机制 OpenGL/ES 的渲染管线也是一个典型的图形流水线&#xff08;Graphics Pipeline&#xff09;&#xff0c;包括多个阶段&#xff0c;每个阶段都负责对图形数据进行处理。管线的核心目标是将图形数据转换为最终的图像&#xff0c;这些图像可以显示在屏幕…

PHP post 数据丢失问题

max_input_vars是PHP配置选项之一&#xff0c;用于设置一个请求中允许的最大输入变量数。它指定了在处理POST请求或者通过URL传递的参数时&#xff0c;PHP脚本能够接收和处理的最大变量数量。 max_input_vars的默认值是1000&#xff0c;意味着一个请求中最多可以包含1000个输入…

Mac下Python版本管理,适用于pyenv不起作用的情况

前言 声明&#xff1a;之前也在网上看到过可以使用pyenv来管理python版本&#xff0c;但由于作者的python安装路径实在是繁杂不堪&#xff0c;因此安装完成pyenv体验下来没有任何用处&#xff0c;但偶然发现vscode似乎可以看到各个python版本&#xff0c;因此写下这篇博客记录…

什么是完全前向保密(PFS)?

在当今数字化时代&#xff0c;信息安全至关重要。而密码学中的完全前向保密&#xff08;Perfect Forward Secrecy&#xff0c;简称PFS&#xff09;技术&#xff0c;已经成为保障信息安全的关键一环。如果没有完全前向保密&#xff0c;一旦长期密钥被泄露&#xff0c;攻击者就可…

计算机毕业设计SpringBoot+Vue.jst在线文档管理系统(源码+LW文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Vulnhun靶机-kioptix level 4-sql注入万能密码拿到权限ssh连接利用mysql-udf漏洞提权

目录 一、环境搭建信息收集扫描ip扫描开放端口扫描版本服务信息指纹探测目录扫描 二、Web渗透sql注入 三、提权UDF提权修改权限 一、环境搭建 然后选择靶机所在文件夹 信息收集 本靶机ip和攻击机ip 攻击机&#xff1a;192.168.108.130 靶机&#xff1a;192.168.108.141 扫描…

【NLP 31、预训练模型的发展过程】

人的行为&#xff0c;究竟是人所带来的思维方式不同还是与机器一样&#xff0c;刻在脑海里的公式呢&#xff1f; 只是因为不同的人公式不同&#xff0c;所以人的行为才不同&#xff0c;可这又真的是人引以为傲的意识吗&#xff1f; 人脑只是相当于一个大型、驳杂的处理器&#…

K8S下redis哨兵集群使用secret隐藏configmap内明文密码方案详解

#作者&#xff1a;朱雷 文章目录 一、背景环境及方案说明1.1、环境说明1.2、方案一&#xff1a;使用配置文件设置密码1.3、方案二&#xff1a;使用args 的命令行传参设置密码 二、redis secret configmap deployment参考2.1 创建secret-redis.yaml参考2.2 修改configmap配置参…