DFS算法及应用(一)

简介: DFS(深度优先搜索)是一种图遍历算法,常用于解决穷举问题,如全排列、迷宫问题、图的连通性等。它沿着树的深度分支进行探索,直至达到叶子节点,若无法继续则回溯。例如,将数字6拆分为3个正整数的递增序列问题可以通过DFS实现,类似地,分糖果问题和买瓜问题同样可以用DFS求解。DFS通常涉及递归或栈结构,通过标记已访问节点避免重复。在编程中,会定义递归函数,设定结束条件,然后枚举可能的情况,并处理下一层节点。

DFS简介


搜索算法:穷举问题解空间所有情况


深度优先搜索:既暴力枚举,尽可能一条路走到底,走不了再回退


给定一个数字x,将其拆分成3个正整数,后一个要求大于等于前一个,给出方案.


  • 就需要实现n重循环
  • n重循环=特定的树状结构=DFS搜索


给定一个数字x=6,将其拆分成3个正整数,后一个要求大于等于前一个,给出方案。



DFS模板


def dfs(depth):
    
    if depth == n:
        # 递归的出口
        return
 
    # 每次循环做的枚举操作


例题:


分糖果


两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法。糖果必须全部分完。两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法。糖果必须全部分完。


ans = 0  # 方案数
 
 
def dfs(depth, n, m):     # 每一层都有枚举
    # depth 第几个小朋友
    # n,m为剩余量
    if depth == 7:   # 不管还剩多少,dfs都结束了,如果剩余为零则说明ans加一
        if n == 0 and m == 0:
            global ans
            ans += 1
        return
    for i in range(0, 6):
        for j in range(0, 6):   # i+j是第一个小朋友的全部糖
            if 2 <= i + j <= 5 and i <= n and j <= m:
                dfs(depth + 1, n - i, m - j)
 
dfs(0,9,16)
print(ans)
 
# 5067671


在写dfs函数时,要先写出递归的结束深度,以及在此处的判断,然后写出分糖果的一一枚举情况,最后写出下一层(下一个小朋友)的情况。


买瓜


小蓝正在一个瓜摊上买瓜。瓜摊上共有n个瓜,每个瓜的重量为A;小蓝刀功了得,他可以把任何瓜劈成完全等重的两份,不过每个瓜只能劈一刀。小蓝希望买到的瓜的重量的和恰好为m。请问小蓝至少要劈多少个瓜才能买到重量恰好为m的瓜。如果无论怎样小蓝都无法得到总重恰好为m 的瓜,请输出—1。


输入的第一行包含两个整数n,m,用一个空格分隔,分别表示瓜的个数和小蓝想买到的瓜的总重量。


第二行包含n个整数A,相邻整数之间使用一个空格分隔,分别表示每个瓜的重量。



def dfs(depth, weight, cnt):   # 写之前要明确参数,这是第几个瓜,目前买到的质量是多少,目前劈瓜几次
    # 第depth个瓜
    # 当前买到瓜的重量
    # 劈了多少次
 
    # 剪枝
    if weight > m:    # 剪枝的出口
        return
    if weight == m:
        global ans
        ans = min(ans, cnt)
    if depth == n:   # 正常的出口
        return
 
    # 不买
    dfs(depth + 1, weight, cnt)
    # 买
    dfs(depth + 1, weight + A[depth], cnt)
    # 卖一半
    dfs(depth + 1, weight + A[depth] // 2, cnt + 1)
 
 
n, m = map(int, input().split())   # 买n个瓜,希望买到的总质量为m
m *= 2
A = list(map(int, input().split()))
A = [x * 2 for x in A]
ans = n + 1  # 表示每个挂=瓜都劈一次
dfs(0, 0, 0)
if ans == n + 1:
    ans = -1
print(ans)
 


  • 为了避免除以二造成的精确度缺失,我们对小蓝所期望的总质量m和每个瓜的质量A乘以二,可以默认劈瓜的次数为n+1,如果递归搜索完成还没有得到m,就让ans等于-1。


  • 同理depth,weight,cnt分别代表了轮到了第几个瓜,当前搜索到的总质量,劈瓜的次数。


  • 我们先写出函数的结束,既depth == n ,然后到了枚举阶段,上个案例是每次分给小朋友的糖果数,这次是根据劈不劈瓜分成三种情况。最后还有剪枝的回退,写入前段部分。


3 10

1 3 13

2



DFS算法及应用(二)+https://developer.aliyun.com/article/1544415?spm=a2c6h.13148508.setting.18.1fa24f0eaie4S4

相关文章
|
17小时前
|
自然语言处理 算法 搜索推荐
分词算法的基本原理及应用
分词算法的基本原理及应用
|
6天前
|
存储 自然语言处理 算法
位运算入门及简单算法题的应用
位运算入门及简单算法题的应用
12 1
|
2天前
|
存储 算法 安全
MD5哈希算法:原理、应用与安全性深入解析
MD5哈希算法:原理、应用与安全性深入解析
|
2天前
|
算法 安全 Java
AES加解密算法:原理、应用与安全性解析
AES加解密算法:原理、应用与安全性解析
|
4天前
|
算法 程序员 数据处理
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
【数据结构与算法】使用单链表实现队列:原理、步骤与应用
|
4天前
|
存储 算法 编译器
【数据结构与算法】使用数组实现栈:原理、步骤与应用
【数据结构与算法】使用数组实现栈:原理、步骤与应用
|
4天前
|
存储 算法
【数据结构和算法】---二叉树(2)--堆的实现和应用
【数据结构和算法】---二叉树(2)--堆的实现和应用
7 0
|
6天前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
|
8天前
|
算法 索引
DFS算法及应用(二)
回溯:回溯就是DFS的一种,在搜索探索过程中寻找问题的解,当发现不满足求解条件时,就回溯返回,尝试其他路径。
|
4天前
|
机器学习/深度学习 自然语言处理 算法
m基于深度学习的OFDM+QPSK链路信道估计和均衡算法误码率matlab仿真,对比LS,MMSE及LMMSE传统算法
**摘要:** 升级版MATLAB仿真对比了深度学习与LS、MMSE、LMMSE的OFDM信道估计算法,新增自动样本生成、复杂度分析及抗频偏性能评估。深度学习在无线通信中,尤其在OFDM的信道估计问题上展现潜力,解决了传统方法的局限。程序涉及信道估计器设计,深度学习模型通过学习导频信息估计信道响应,适应频域变化。核心代码展示了信号处理流程,包括编码、调制、信道模拟、降噪、信道估计和解调。
26 8