DFS入门问题数的全排列全面解析

问题:P1706 全排列问题

刚开始学DFS的时候,我也感觉很迷惑,不知道它的来龙去脉,刷了些题之后也是感觉懵懵懂懂的,只能尝试套模版,但随着学习的深入,学了BFS,背包问题等更复杂的算法之后终于对搜索有了更全面的认识。如果你和我之前一样对搜索感到迷惑的话,千万不要放弃,争取每次理解一点,随着学习的深入,一定会慢慢体会到它的精髓的。加油,朋友!

我们可以把它当成把1-n的扑克牌放到n个小盒子的过程。整个的求解过程就是一个搜索过程,依次尝试每一种可能,最外层一个for()循环来枚举1号位置,然后再自身调用自己的for()循环来枚举2号,然后在自身调用自己的for循环来枚举3号,依次类推。

举例:当n==3时

1号盒可能的情况1(2,3),然后枚举2号可能的情况2(3),最后3号盒只能放3(第一种123),回到2号盒,尝试剩余的3号,到了3号和,只能放2号(第二种132),现在2号盒和3号盒都枚举完了。

1号盒枚举2号(3),然后枚举2号盒可能的情况1(3),到了3号盒只放3(第三种213),回到2号盒枚举剩余的3,来到3号盒只能放1(第四种231),

1号盒剩余的3,然后枚举2号盒可能的情况1(2)到了3号盒只能放2(第五种312),然后回到2号盒尝试剩余的2,到了3号盒只有1(第六种321

其实搜索的过程就是枚举的过程,也是搜索的过程,对每一个可能的路径搜索到不能深入为止,而且每个节点只访问一次。实现如下:

#include <stdio.h>
int n,book[100000],a[100000];   //book记录该点是否放过   a记录排列情况
void dfs(int step){
    if(step==n+1){              //当走到盒子外的时候说明已经完成了一次全排列,输出
        for(int i=1;i<=n;i++)
            printf("%5d",a[i]);
        printf("\n");
        return ;               //回到前一个盒子
    }

    for(int i=1;i<=n;i++){
        if(!book[i]) {         //判断该点是否有数字
            a[step]=i;         //放入数字
            book[i]=1;         //记录
            dfs(step+1);       //尝试下一个盒子的可能情况  
            book[i]=0;         //收回该盒子的数字
        }
    }



}
int main() {
    scanf("%d",&n);
    dfs(1);          //搜素从1号盒开始
    return 0;
}

建议题目:E - 迷宫问题

                  D - Oil Deposits

                  F - Tempter of the Bone

                 C - Prime Ring Problem 

参考资料:百度百科——深度优先搜索

                  图的遍历之 深度优先搜索和广度优先搜索

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值