【动态规划——排列】-创新互联

排列

[题目链接]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。
代码
#includeusing 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<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;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章标题:【动态规划——排列】-创新互联
标题链接:http://scyanting.com/article/dhsooo.html