2021.12.9 学习总结

这篇博客探讨了深度优先搜索(DFS)和广度优先搜索(BFS)的基本概念,并通过实例解释了它们在解决实际问题中的应用。文中以夫子云游问题为例,展示了如何使用DFS解决递归问题,同时讲解了错误判断条件的修正。此外,还介绍了动态规划(DP)在解决数字三角形问题中的应用,给出了求解最大路径权值的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单学习了一下搜索,写了一道关于搜索的题目。

dfs就是一条路走到底,发现没路了,返回来,走另一条路。

bfs就是每条路都走一点,走一点点后就走另一条路了。

BFS:

BFS类似于水波纹的扩散,在求解一些最短路径,最优值问题的时候效率很高。
BFS为了遍历,需要保存所有的状态,对空间来说是一个巨大的消耗。(因为通常是无法递归实现的)


DFS:

DFS主要应用于回溯的搜索问题中,比如迷宫问题,岛屿问题。
DFS能够做到使用一个状态变量去搜索所有的状态空间,这对空间的消耗来说,是非常节约空间的(通常使用递归实现)。
 

写的那个题主要用到了递归的思想以及简单的dfs,先判断它的边界,也就是判断它结束的条件,如果符合就返回上一步继续搜索下一种方案,循环反复把所有符合的都找出来,就是搜索。

问题 I: 夫子云游

题目描述

改编自猫腻所著的同名小说《将夜》目前正在火热开播,其中男主角宁缺在考书院二层楼时遇一题“那年春,夫子出国游历,遇桃山美酒,遂寻径登山赏桃品酒,一路摘花饮酒而行,始斩一斤桃花,饮一壶酒,后夫子惜酒,故再斩一斤桃花,只饮半壶酒,再斩一斤桃花,饮半半壶酒,如是而行……至山顶,夫子囊中酒尽,惘然四顾,问:夫子一共斩了几斤桃花,饮了几壶酒?”而当我们的男主角宁缺看到这道题目时,更是直接来了句“谁出的这道题,太二了”,紧接着就提笔写下了“夫子饮二壶酒,斩尽满山桃花”后直接就交卷走人了赢得书院弟子的大赞。

今夫子再次游历,他提着酒壶,从出院出来,酒壶中有酒2斗,他边走边唱:

    无事街上走,提壶去打酒。
    逢店加一倍,遇花喝一斗。

这一路上,他一共遇到店M(0<M<=10)次,遇到花N(0<M<=10)次,已知最后一次遇到的是花,他正好把酒喝光了。

请计算夫子遇到店和花的合理的次序种数。

可以把遇店记为a,遇花记为b,如果M=5,N=10。则:babaabbabbabbbb 就是合理的次序之一。

输入

M、N 分别为遇到店和花的次数

输出

所有可能店和花次序方案的个数

样例输入 Copy

5 10
样例输出 Copy

14

#include<stdio.h>
int N,M,sum;
void dfs(int a,int b,int c) //店花酒
{
    if(a==0 && b==1 && c==1)
    {
        sum++;
        return;
    }
    else
    {
        if(c<=0 || c>b)
        {
            return;
        }
        if(a<M &&a>0)
        {
          dfs(a-1,b,2*c);
        }
        if(b<N && b>0)
        {
            dfs(a,b-1,c-1);
        }
    }
}

int main()
{
    sum=0;
    scanf("%d%d",&M,&N);
    dfs(M,N,2);
    printf("%d\n",sum);
    return 0;
}
//有错还没改对,大概思想就是如此

 彭哥教了我一下,原本的判断条件a<M,但是刚进入函数时a=M,不可能成立,不会进行下一步的递归。而且a只会减小不会增大不需要判断是否小于M。

改完以后:

#include<stdio.h>
int N,M,sum;
void dfs(int a,int b,int c) 
{
	//printf("%d  %d  %d  %d\n",a,b,c,sum);
    if(a==0 && b==1 && c==1)
    {
        sum++;
        return;
    }
    else
    {
        if(c>0 && a>0 && c<=b)
        {
          dfs(a-1,b,2*c);
        }
        if(b>0 && c>0 && c<=b)
        {
            dfs(a,b-1,c-1);
        }
    }
}

int main()
{
    sum=0;
    scanf("%d%d",&M,&N);
    dfs(M,N,2);
    printf("%d\n",sum);
    return 0;
}

学习了一点儿dp。

题目1:数字三角形问题

从顶部向下走,每次只能走下面或者右下,走完全程,问你怎么走使得权值最大。

输入:

5

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

输出:

30

题目链接:NYOJ 18 The Triangle 填表法,普通dp - 西*风 - 博客园 

#include<stdio.h>
int max,n,a[2000][2000],b[2000][2000];
//a储存原始三角形信息,b储存最大路径权值的和
int main()
{
    int i,j;
    scanf("%d",&n);
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=i; j++)
        {
            scanf("%d",&a[i][j]);
            b[i][j] = a[i][j];
        }
    }
    for(i=n-1; i>0; i--)  //二维数组最后一行
    {
        for(j=1; j<=i; j++)  //二维数组第一行
        {
            if(b[i+1][j]>b[i+1][j+1])  //自底向上比较取最大值加和
            {
                max = b[i+1][j];
            }
            else
            {
                max = b[i+1][j+1];
            }
            b[i][j] += max;
        }
    }
    printf("%d",b[1][1]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值