2021-08-01

最近一直都在写洛谷的题目,其中有许多题目涉及到了DFS,在自己查找资料和学习总结后感觉递归这方便过于抽象,借此也像对此有更深的理解
所谓DFS就是指:优先考虑深度,换句话说就是一条路走到黑,直到无路可走的情况下,才会选择回头,然后重新选择一条路。

## **题目描述**

就先看下我遇到这种类型时候的第一次看到的题目
![在这里插入图片描述](https://img-blog.csdnimg.cn/0f99f14df30f4952ac52d6ac1d09864a.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pqc3J1X0JlZ2lubmVy,size_16,color_FFFFFF,t_70)
https://www.luogu.com.cn/problem/P1036
网站我也放这


## **草率的分析**

第一眼就是肯定就是枚举了,更深层次的算法我也没有学到.......
然后就是枚举的过程
首先就是组合数的知识 一眼就知道是c (n,k)算一下复杂度也可以接受
枚举所有的结果之后直接写一个判断素数的函数带入就可以了
那么重点就在怎么枚举这个
然后就没有然后了.....

## DFS原理和使用
引导题:输入一个数n,输出n的全排列
可以先把这个问题形象化
如:
假如有编号为1,2,3的3张扑克牌和编号为1,2,3的3个盒子。将这3张扑克牌分别放入3个盒子一共有几种不同的放法呢?
 
 然后我们对这个简单的情况用dfs的思想
 我们可以想象成将123三个数字放在有序的三个盒子里(这也是组合的思想)
 在此当我们一个数已经放好了之后 设置一个book类型的数组对其标记
 接下来我们只要按顺序放就好了完成123之后我们对其收回
 按照上面的逻辑。小明将3号盒子的3号扑克牌取出,但手上仍然只有3号扑克牌。
所以小明只好回到2号盒子,收回2号扑克牌,此时手中有2,3号扑克牌。
按照之前的约定,往2号盒子放3号扑克牌,然后小明又继续往前走,此时手里只有2号扑克牌,把2号扑克牌放入3号盒子里,此时完成了第二种排序。(这里就是dfs的体现)
以此类推....
递归的思想在此就不再赘述
放一下这个的ac代码

```
#include<stdio.h>
int a[10],book[10],n;
//这里还有需要注意的地方C语言全局变量默认为0

void  dfs(int step){ //此时在第step盒子面前,需要往里面放第i张扑克牌
    int i;
    if(step==n+1){    //这里说明前面的n个盒子已经放好了,这是dfs结束的标志 
        for(i=1;i<=n;i++)
            printf("%d",a[i]);
        printf("\n");
        
        return ;
        /* 
        注意这个 return 它的作用不是返回主函数,而是返回上一级的dfs函数
        
        例:如果此时是  dfs(5),遇到这个 return 就会回到上一级的 dfs函数 
        也就是dfs(4),但此时dfs(4)的大部分语句已经执行了,只需要接着执行 book[i]=0
        然后继续进入for循环进入下一次的 dfs函数,直到结束。         
        */ 
        
    }
     for(int i=1;i<=n;i++){
        if(book[i]==0){  //说明i号扑克牌还在手里,需要放入step号盒子
            a[step]=i;//将i号扑克牌放到第step个盒子中
            book[i]=1;//此时i号扑克牌已经被使用        
            dfs(step+1);
            /*注意这里是自己调用自己,表示此时走到了第step+1个盒子面前*/        
            book[i]=0;
            /*book[i]=0表示dfs调用结束了,换句话说就是扑克牌已经全部放完了
              需要按照顺序将扑克牌收回,重新放,也就是前面所说的
             */
        }
    }
    return;//这里表示这一级别的dfs函数已经结束了,返回上一级 dfs函数 

}
int main(){
    scanf("%d",&n);
    dfs(1);   //dfs函数的开始 
    return 0;
}

```
## 总结
我个人认为这个思想还是非常重要的
需要自己琢磨好久然后自己理解才能充分使用的
就我最近的做题情况来说遇到好多这个类型的了
上面的那个题目的ac代码自己的就不放了 (其实还有些情况没过)
网站在上面可以自己区里面找解析
 
撒花    2021/8/1 计算机202 zj
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值