【动态规划——排列】

排列

[题目链接]https://www.acwing.com/problem/content/825/

题意

求将1~n个整数排成一排有多少种不同的排法

思路

  1. 共3位数,有三个能够存放数字的位置,用u代表第几个能存放数字的位置
  2. 从第一个位置,即从u=1开始递归,从数字1到3进行考虑所有情况,放过的数字则不能进行第二次放置
  3. 当放置到最底层,即u=n时,开始返回进行上一层的递归(返回现场),同时取消标记第三个位置存放的数

递归搜索树在这里插入图片描述
搜索历程在这里插入图片描述

坑点

  1. 按照字典序排列
    字典序——按照字典中的顺序排列,如在英语字典中以a、b、c……z的顺序排列,对于数字则是以1、2、3…n的顺序排列
实现步骤
  1. 定义两个数组,一个为st(state)记录每个数的状态,即该数字是否被标记,默认st数组的值为0(没有被标记),当被标记时,数组值则为1,另一个为q,记录每一个填入u位置的数字
  2. 在主函数中定义一个dfs函数,初始值为1,即u的值,从第一个能够存放数字的位置开始
  3. 当u>n,即超出最底层时,说明已经数字已经填到了最后一个空,此时可以输出数组q中的数字
  4. 当u没有到最底层时,利用for循环从1到n开始给每一个u上的数赋值
  5. 判断赋值的数是否被标记,当数组st的值不为0时,则说明该数没有被标记,可用,此时将 i 赋值给q[u](从1到n循环遍历每一个位置上被放置的数字)
  6. 此时,将数组st的值改为1,表示上述填过的数字被标记为已使用过,后面不可用
  7. 继而利用dfs(u+1)进行下面一层一层的递归
  8. 当从每个下一层出来,返回上一层,进行上一个存放数字位置的填空时,此时的数字状态需被改为未被标记的状态,即st[i]=0。
代码
 #include <bits/stdc++.h>
using namespace std;
int n;                                           //输入的整数n
int st[15];                           //判断数字状态为0还是1,默认值为0,表示被使用过,为1则表示没有使用过
int q[10];                                      //表示输出的n个数字排成的一排
void dfs (int u)
{
    if (u>n)                            //当数字已经填到大于n的空时
    {
        for(int i=1;i<=n;i++)
        {
            cout<<q[i]<<" ";           //输出当前的数字
        }
        cout<<endl;
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if (!st[i])              //否则,当st[i]没有被使用过时
            {
                q[u]=i;              //从1到n循环遍历每一次存放数字的位置
                st[i]=1;    //在当前位置存放一个数后,该数字状态被标记为已使用过(字典序要求),后面不可用
                dfs(u+1);   //进行下一层的函数递归
                st[i]=0;//从下一层出来往上返回进行上一个存放数字位置的填空时,此时的数字状态变为未被标记
            }
        }
    }
}
int main ()
{
    cin>>n;
    dfs(1);                                           //定义一个函数,初始值为1,因为从第一个位置开始填数字
    return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值