BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山

这篇具有很好参考价值的文章主要介绍了BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

BFS,DFS的应用场景区别

 具体题目来看:

        DFS适合于“找出一条可行的路径(是否可到达问题)”,“要遍历所有点一遍”,“组合排列类问题”之类

        BFS适合于“找最短路(权值为1)”,“层序遍历概念”

对于题目过程的感觉(我每次都是靠这个)

DFS对于数据像栈stack,后入栈的先出(从底层向上层回溯过程),而BFS是直接借助了队列,先进先出;以后遇到搜索题目,想题目过程,是后进入的被删除,还是先进去的被删除,像stack还是queue。

//DFS模板
int dfs(int u)
{
    st[u] = true; // st[u] 表示点u已经被遍历过

    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}

//BFS模板
queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);

while (q.size())
{
    int t = q.front();
    q.pop();

    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}

当然,其实很多时候两个都可以,只是优化的问题。 

 DFS的注意点

顺序

用什么样的顺序去把题目所有可能不漏的暴搜一遍,正常从搜索树角度去分析会更有条理。

排列数字

 常见的全排列顺序枚举(排列型枚举)所有可能;

BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山,搜索与图论,宽度优先,深度优先,算法,数据结构,图论,图搜索算法

 指数型枚举所有可能,即考虑每个元素选与不选两种情况:

n皇后问题

枚举每个格子放与不放皇后,共个格子都这样

BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山,搜索与图论,宽度优先,深度优先,算法,数据结构,图论,图搜索算法

 DFS什么时侯要回溯?(小猫爬山有具体题目分析)

DFS的本质就是在每一步做出不同选择,当这个选择可做可不做时,一般就要回溯。

因为选择选下了,会对后面的操作有影响(例:迷宫问题,你选择走(i,j)这步,再递归(i,j)四周作为下一步,而当这个系列的dfs走完了,你并没有清除查重数组st中的值,则后续这些点都无法在被遍历到了)。

回溯就是要消除搜索过程中不同可能性情况间的影响(迷宫问题:你走完(i,j)后,失败了,要把相关点的st数组清0,不要影响下一个情况走到这些点)

不需要回溯的常见情况:

        当遇到一个选择,一定要对它操作时,就不需要回溯,例如要求所有格子的格子,要标记所有情况,找到一个点就要标记res++;如果取消标记,那么res会被重复计算。

例子:

树图的标记问题:树的重心

排列数字:(如上图所示) 当你枚举第三位后,结果输出“1 2 3”,之后要回头找其他可能情况,先回溯到第二位,初始1在第一位(bool[1]=1),而2已经枚举过了,所以枚举3,所以要在第三位回溯时,把3弃掉(bool[3]=0);

DFS的优化剪枝(具体题目分析见下文:小猫爬山)

  1.  优化DFS时的搜索顺序:数据的顺序不同会对DFS的效率产生很大影响,原则是“大部分情况下,我们优先搜索分支较小的节点”
  2. 排除等效冗余:对于两个不同的状态,能够到达的搜索子树是等效的,那么一边就不走——注意这里不是“相同”而是“等效”,就算两个状态不同,如果它们对答案的影响都是相同的,就算作是“等效”的了。(实际上排除等效冗余就是提前预判是不是会产生重复)
  3. 可行性剪枝:当前选择违反题目条件/不可能到达答案,直接return结束
  4. 最优性剪枝:当前答案已经不优于现在的最优解,直接return结束
  5. 记忆化搜索:DP,换赛道了属于是。(选择DP,拥抱美好生活)

小猫爬山

BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山,搜索与图论,宽度优先,深度优先,算法,数据结构,图论,图搜索算法

 本题有一种错误的贪心思想考虑:把猫猫按从小到大排序,再从小到大枚举小猫,尽可能把几个小的放在一个缆车里。

这样想太片面了,我们不是也可以把一个大的配一个小的吗?(例如:1,2,3,97,98,99情况。第一种考虑4辆,而第二种3辆)。

正确想法:

对于一只猫,要么和其他猫挤一辆车,要么自己坐一辆车,两种选择,用深度优先搜索。对于dfs函数种的变量(写我们关心的变量):现在在考虑哪种小猫,已经租了几台缆车,每辆缆车上搭载小猫质量总和。

dfs(now,cnt)//now:第几只猫:cnt:已经用了几量车;num[i]:第i辆车上小猫质量和

1.和其他猫挤一辆车

        枚举每个已有的缆车能否搭载小猫now:满足约束条件(now质量+num[i]<=缆车最大承重),则小猫now放在缆车i上,在找dfs(now+1,cnt);小猫now在缆车i上情况结束要回溯到小猫now还没车放时状态,继续枚举已有的缆车;

2.自己坐一辆车

num[cnt+1]=小猫now的重量;//cnt+1即新的缆车;把小猫now放在缆车从cnt+1上,再dfs(now+1,cnt+1)//找小猫now+1要放的车,现在又cnt+1辆缆车了;最后小猫now放在cnt+1车的情况结束后,也要回溯,不回溯的话,此时的cnt+1这个车上永远有小猫now的重量,会对其他情况产生影响。

#include <algorithm>
#include <iostream>

using namespace std;

const int N = 2e1;

int cat[N], cab[N];
int n, w;
int ans;

bool cmp(int a, int b) {
    return a > b;
}

void dfs(int now, int cnt) {
    if (cnt >= ans) {//最优性剪枝
        return;
    }
    if (now == n + 1) {
        ans = min(ans, cnt);
        return;
    }
    //尝试分配到已经租用的缆车上
    for (int i = 1; i <= cnt; i++) {  //分配到已租用缆车
            //可行性剪枝
        if (cab[i] + cat[now] <= w) {
            cab[i] += cat[now];
            dfs(now + 1, cnt);
            cab[i] -= cat[now];  //还原
        }
    }

    // 新开一辆缆车
    cab[cnt + 1] = cat[now];
    dfs(now + 1, cnt + 1);
    cab[cnt + 1] = 0;
}

int main() {
    cin >> n >> w;
    for (int i = 1; i <= n; i++) {
        cin >> cat[i];
    }

    sort(cat + 1, cat + 1 + n, cmp);//优化搜索顺序 

    ans = n;

    dfs(1, 0);

    cout << ans << endl;

    return 0;
}

关于本题的DFS优化:

优化DFS时的搜索顺序:

首先小猫重量用什么样的顺序去被搜索,从小到大?从大到小?根据上文的原则,我们应该从大到小搜索,因为重量大的猫明显选择会少有些(要比小重量更难和别的猫挤车),从而搜索的分支会更少。

排除等效冗余:

本题没有分析出会出现情况等效可能(排除等效冗余用的不多)

可行性剪枝:

在放猫now放入之前的车时,要加入限制条件:(now质量+num[i]<=缆车最大承重)

最优性剪枝:

若现在运行情况的res已经>=ans,则无需继续了,不可能是最优解了。

 文章来源地址https://www.toymoban.com/news/detail-835687.html

到了这里,关于BFS,DFS的应用场景及DFS的注意点,具体题:165.小猫爬山的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度优先搜索(DFS、深搜)和广度优先搜索(BFS、广搜)

    目录 深度优先搜索(DFS、深搜)和广度优先搜索(BFS、广搜) 深度优先搜索(简称“深搜”或DFS) 广度优先搜索 总结 深度优先生成树和广度优先生成树 非连通图的生成森林 深度优先生成森林 广度优先生成森林 图 1 无向图 深度优先搜索的过程类似于树 的先序遍历 ,首先

    2024年01月20日
    浏览(48)
  • 深度优先搜索(DFS)和广度优先搜索(BFS),用代码讲原理

    以图文的形式对深度搜索和广度搜索的理论进行讲解时,可能会对一些概念有些模糊,且不太清楚怎么把该理论用程序的方式进行复现并解决这一搜索问题(这说的就是本人) 。所以后面我看完了一份实现这两种搜索方法的代码,在这做一个笔记,希望对大家有所帮助。 两

    2024年04月12日
    浏览(50)
  • BFS算法(宽度优先搜索)超强解析 BFS迷宫问题图文详解 DFS与BFS的区别

      前情回顾:DFS练习-迷宫(最短路径)问题详解 一波三折 图片+文字 以及你需要会的基础:手搓数据结构之队列queue C/C++语言版(BFS算法预备知识) 广度优先搜索(Breadth First Search)简称广搜或者 BFS, 是遍历图存储结构的一种算法 。 BFS的原理是 “逐层扩散” ,从起点出发

    2024年02月22日
    浏览(46)
  • 深度优先搜索(DFS)和广度优先搜索(BFS)两种算法c++

    深度优先搜索(DFS)和广度优先搜索(BFS)是一种用于遍历或搜索树图的一种算法,在这个过程中保证图或数的每个结点被访问且仅被访问一次,再按照每个结点访问的顺序不同分为深搜和广搜。 本文只讨论这两种算法在搜索方面的应用! 深度优先搜索 ( Depth-First-Search,DFS )它 沿

    2024年02月13日
    浏览(47)
  • Python 算法基础篇:深度优先搜索( DFS )和广度优先搜索( BFS )

    深度优先搜索( DFS )和广度优先搜索( BFS )是两种常用的图遍历算法,用于在图中搜索目标节点或遍历图的所有节点。本篇博客将介绍 DFS 和 BFS 算法的基本概念,并通过实例代码演示它们的应用。 😃😄 ❤️ ❤️ ❤️ 深度优先搜索( DFS )是一种用于遍历或搜索图或树

    2024年02月07日
    浏览(65)
  • 【算法手札】深入理解宽度遍历(bfs)和深度遍历(dfs)搜索

        算法的重要性不言而喻,现在我们的生活也已经离不开各种算法,一个好的算法能大大提高程序的运行效率,是学习编程的一个重要模块,而遍历算法也是算法里的一个大的模块,今天我们一起来学习一下深度遍历算法(depth first search)和 广度优先遍历(broad first searc

    2024年02月21日
    浏览(43)
  • 图的遍历——深度优先搜索(DFS)与广度优先搜索(BFS)(附带C语言源码)

    个人主页:【😊个人主页】 系列专栏:【❤️数据结构与算法】 学习名言:天子重英豪,文章教儿曹。万般皆下品,惟有读书高——《神童诗劝学》 第一章 ❤️ 学前知识 第二章 ❤️ 单向链表 第三章 ❤️ 递归 … 在此之前我们学习过了图的一些基本概念,如同在二叉树

    2024年02月06日
    浏览(65)
  • 【数据结构与算法】搜索算法(深度优先搜索 DFS和广度优先搜索 BFS)以及典型算法例题

    【数据结构与算法】系列文章链接: 【数据结构与算法】递推法和递归法解题(递归递推算法典型例题) 【数据结构与算法】系列文章链接: 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题 【数据结构与算法】系列文章链

    2024年04月13日
    浏览(63)
  • 图搜索算法详解 - DFS、BFS、Bellman-Ford、Dijkstra

    图搜索算法是许多应用程序的基础,例如社交网络分析、路径规划、数据挖掘和推荐系统。在本文中,我们将深入探讨图搜索算法的世界,探索它们的定义、重要性和实际应用。 图搜索算法是一种用于遍历图的技术,图是由 关系 连接的 节点集合 。在社交网络、网页或生物

    2024年02月16日
    浏览(40)
  • 图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

    从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次。(连通图与非连通图) 1、访问指定的起始顶点; 2、若当前访问的顶点的邻接顶点有未被访问的,则任选一个访问之;反之,退回到最近访问过的顶点;直到与起始顶点相通的全部顶点都访问完毕; 3、若

    2024年01月17日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包