AcWing 93. 递归实现组合型枚举 题解

题目

AcWing 93. 递归实现组合型枚举 题解_第1张图片
AcWing 93. 递归实现组合型枚举 题解_第2张图片


思路

AcWing 93. 递归实现组合型枚举 题解_第3张图片
拿到这道题,首先根据题意,对着一个样例画出搜索树,然后再从搜索树扩展出来的原理抽象出代码
这道题是依次枚举每个位置,枚举每个位置上可以填的树。
然而123和321和231是一种情况,且只认123
每种符合条件的情况必须是升序排列的
因此在我们枚举一个位置可以填的数的时候,也必须是升序的进行枚举,当前枚举的这个可能的数必须比之前枚举过的数要大
因此,我们这里的dfs函数参数为:

  • 当前该枚举哪个位置
  • 最小可以从哪个开始枚举

这样就可以得到符合条件的结果。


代码

#include
#include
using namespace std;
const int N=30;
int n,m;
int  ways[N];  //存储答案的,长度只用到1-m
void dfs(int u,int start)
{
    if(u-1+n-start+1<m) return;  //u-1是已经填在答案里的数的个数   n-start+1是剩下的可以填在答案里的,加起来比m小,说明这种情况肯定没答案,作一次剪枝
    if(u>m)   //如果当前枚举的数已经比m大了,就是m个数枚举完了
    {          //把答案输出
        for(int i=1;i<=m;i++)
            printf("%d ",ways[i]);
        printf("\n");
        return;
    }
    for(int i=start;i<=n;i++)    //当前可以从start开始枚举
    {
        ways[u]=i;          //枚举start-n的每种情况
        dfs(u+1,i+1);      //向下递归
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    dfs(1,1);  //最初是当前从1开始枚举,当前最小可以枚举1
    return 0;
}

//这里为什么没有st数组,判断每个数是否被用过?
//因为这里有了开始枚举的下标start,枚举过的数的下标都比start小,已经过滤掉了,替代了st数组的作用。

你可能感兴趣的:(#,蓝桥杯,code,刷题,总结&记录,dfs)