acwing dfs 递归实现排列型枚举

大家好,这是第三次讲解dfs这是最后一次讲解例题了,这里dfs我给大家找几个例题把例题网站也给大家写上,大家昨晚我给大家下次放答案代码,然后讲解一些题目细节,我上次说了给大家整点这块内容的acm模板,大家自行理解,博主理解不了也讲不了,有大佬可以给解释下,不胜感激。

下次就讲BFS的内容了,上这次内容代码(讲解方式还是代数法理解)。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10;

int n;
int state[N];   // 0 表示还没放数,1~n表示放了哪个数
bool used[N];   // true表示用过,false表示还未用过

void dfs(int u)
{
    if (u > n)  // 边界
    {
        for (int i = 1; i <= n; i ++ ) printf("%d ", state[i]); // 打印方案
        puts("");

        return;
    }

    // 依次枚举每个分支,即当前位置可以填哪些数
    for (int i = 1; i <= n; i ++ )
        if (!used[i])
        {
            state[u] = i;
            used[i] = true;
            dfs(u + 1);

            // 恢复现场
            state[u] = 0;
            used[i] = false;
        }
}

int main()
{
    scanf("%d", &n);

    dfs(1);

    return 0;
}

然后放一下代数法理解的过程

!!!!!!!!这不是代码这是代数法理解代码的过程,就是具体代码怎么执行操作的,还是老规矩能省篇幅则省,大家看的舒服一点,那个恢复现场的两行代码,第一行可以省不影响ac理解不了的友友们可以忽略,我也没写,但是第二行不能省,博主写下来了
dfs(1);
for(i=1;i<3;i++)//i=1去操作
st[1]=1;
use[1]=ture;//表示这个数用过了
dfs(2);
for(i=1) 由于use[1]=ture//后面的操作全部忽略直接i++
i++; i=2
st[2]=2;
use[2]=ture;
dfs(3);
for(i=1)由于use[1]、use[2]都被用过都等于了ture不满足!use[i]
i++; i=3
st[3]=3;
use[3]=ture;
dfs(4);
u>n printf(1,2,3);//st[1]——st[3]
然后回溯dfs(3)
use[3]=flase;//表示没选了
回溯dfs(2)
use[2]=flase;
i++; i=3
st[2]=3 use[3]=ture
dfs(3)for(i=1)use[1]=ture 所以i++ i=2 use[2]=flase !use[i]成立st[3]=2;
use[2]=ture;
dfs(4);
u>n printf(1,3,2);//st[1]-st[3]
use[3]=flase//回溯dfs(3)
use[2]=flase//回溯dfs(2)
回溯dfs(1)
//其实这里一遍循环就完了,剩下的完全可以找猫画虎做出了,但是我还是给大家写完吧,不过一些很简单的注释就不再重复了,大家读代码的时候也需要自己的理解才能进步
use[1]=flase
i++; i=2
st[1]=2;
use[2]=ture
dfs(2);
i=1 st[1]=1;use[1]=ture
dfs(3);
i=1 use[1]=ture i++ i=2 use[2]=ture i++ use[3]=flase
st[3]=3;use[3]=ture;
dfs(4);p(2,1,3);
use[3]=flase
回溯dfs(2);
use[1]flase
i++; i=3
st[2]=3 use[3]=ture;
dfs(3);
i=1 use[1]=flase;st[1]=1 use[1]=ture;
printf(2,3,1);
use[3]=flase;
use[1]=flase;
use[2]=flase;
回溯dfs(1);
i++ i=3
//剩下的大家当思考题吧,自己动手写一下剩下的过程理解一下,博主肝不动了555

讲一下acm模板总么写的,acm模板更强大这可以实现任意数全排列

//枚举排列的俩种常见方法:一是递归枚举,二是用STL中的next_permutation
//这个程序可以随机实现任意数的全排列
#include<iostream>
#include<algorithm>//包含next_permutation
using namespace std;
int main()
{
    int n,p[10];
    cin>>n;
    for(int i=0;i<n;i++)scanf("%d",&p[i]);
    sort(p,p+n);//排序得到p的最小排列
    do{
        for(int i=0;i<n;i++)printf("%d",p[i]);//输出排列p
        puts(" ");
    }while(next_permutation(p,p+n));//求下一个排列
    return 0;
}

1114. 棋盘问题 - AcWing题库

P1683 入门 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)P1025 [NOIP2001 提高组] 数的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值