烤鸡(学习dfs心得体会)

本文通过一道烤鸡配料问题介绍了深度优先搜索(DFS)的概念及其应用。博主分享了自己学习DFS的过程,强调了使用逻辑性思维解决问题的重要性。通过类比全排列问题,解析了DFS解决此类问题的思路,即从1开始递归搜索,满足条件时存储结果并回溯。文中还表达了在遇到困难时查看题解并自我学习的价值。
摘要由CSDN通过智能技术生成

烤鸡

题目来源:洛谷
题目地址:洛谷P2089

题目背景
猪猪 Hanke 得到了一只鸡。

题目描述
猪猪 Hanke 特别喜欢吃烤鸡(本是同畜牲,相煎何太急!)Hanke 吃鸡很特别,为什么特别呢?因为他有 1010 种配料(芥末、孜然等),每种配料可以放 11 到 33 克,任意烤鸡的美味程度为所有配料质量之和。

现在, Hanke 想要知道,如果给你一个美味程度 nn ,请输出这 1010 种配料的所有搭配方案。

输入格式
一个正整数 n,表示美味程度。

输出格式
第一行,方案总数。

第二行至结束,1010 个数,表示每种配料所放的质量,按字典序排列。

如果没有符合要求的方法,就只要在第一行输出一个 00。

输入输出样例
输入
11
输出
10
1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 2 1 1
1 1 1 1 1 1 2 1 1 1
1 1 1 1 1 2 1 1 1 1
1 1 1 1 2 1 1 1 1 1
1 1 1 2 1 1 1 1 1 1
1 1 2 1 1 1 1 1 1 1
1 2 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1

这个题目就是一道典型的dfs。

这篇题解是记录一下我学习的过程哈。

我也是刚入门dfs嘛,这个递归其实对我来说还没那么简单,我一开始的思路就一直在想这个递归到底应该如何去处理,我在想不同的情况应该如何考虑。

因为这个题目的话有1,2,3,三个数嘛,有多种情况,所以一开我就在想,又要递归,又要找这些规律,好麻烦啊!

然后我就看了看题解,发现其实并不难,这个多种情况其实已经包含在了递归里面了。

我做这个题目最大收货就是我学到了dfs应具有的思考问题的方式,应当按照与习惯性思维不同的逻辑性思维去思考。

比如这个题目可以类比到全排列那个题目,那个题目的思想是什么呢?

从1开始深搜,搜到满足条件,然后回溯。

这个题目也是如此。

所以dfs这种深搜问题,我们思考问题的时候应该有一个具体的框架,而不是盲目的去思考。

而且这种问题其实很典型的,这个题目就应当按照一个树形的结构去思考,从一开始往下搜,然后搜到满足条件,就储存然后回溯。

所以如果用常规性思维去乱糟糟的思考的话,这个题目看起来会很复杂,但是如果按照这种逻辑性的思维去思考问题,问题往往就可以迎刃而解。

而且我现在发现有时候有的问题做不来,看看题解,自己懂了,然后有一种学到新知识的感觉真的挺好的。

如果在学习的过程中碰到一个自己不会的题目,就是那种可以动手但是确实难度很大需要好好思考的题目,思考一会儿就可以考虑看看题解,耐心的去看,有信心的去看,去学,真的会发现收货很大很大。

对于本题的话,就是从1开始搜,然后搜到既是十个数然后总和又等于n的话,那就存储下来,如果超过了十个数或者总和已经大于n了,那就回溯,其实这里有一点点剪枝的味道了(因为我没学剪枝所以只是感觉像剪枝)。

这个题对我的帮助还是挺大的,受益匪浅哈哈哈,我以后就这么学,先学一个算法,然后去刷对应的题目,因为刚学这个算法嘛,那肯定很多用到这个算法不会的题目,不会也是很正常的,不要灰心,思考思考,看看题解,然后再理解理解,总结方法,这就是学习一个新算法的过程!!

好了,最后把代码奉上!


```cpp
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int cunfang[11], a[N][11];
int n;
int cengshu = 0;
void dfs(int sum, int total)
{
    if (total == 10 && sum == n)
    {
        for (int i = 0; i < 10; i++)
            a[cengshu][i] = cunfang[i];
        cengshu++;
    }
    else if (total > 10 || sum > n)return;
    else
    {
        for (int i = 1; i <= 3; i++)
        {
            cunfang[total] = i;
            dfs(sum + i, total +1);
            cunfang[total] = 0;//回溯,其实这一步没有也可以,因为这个数据是覆盖式的发展的
        }//写dfs的时候就思考树形结构,我悟了,然后这种动态的问题,配合条件一起思考
    }
    
}
int main()
{
    scanf("%d", &n);
    dfs(0, 0);
    cout << cengshu << endl;
    for (int i = 0; i < cengshu; i++)
    {
        for (int j = 0; j < 10; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
    return 0;
}

对我来说这个题的帮助还是挺大的,要掌握好学习的方法,要一直寻找、摸索、改进学习的方法,让我们高效学习!!

好了,每篇题解后面都附上一句话。

我知道你今天不理我是因为我说话水平真的很低,对不起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值