欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

烤鸡(学习dfs心得体会)

程序员文章站 2022-04-21 16:31:06
...

烤鸡

题目来源:洛谷
题目地址:洛谷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

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

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

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

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

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

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

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

从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;
}

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

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

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