组合数枚举

Description

找出从自然数1、2、… 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。

Input

输入n、r。

Output

按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。

Sample Input

5 3

Sample Output

543
542
541
532
531
521
432
431
421
321

思路:对于每个数我们可以选也可以不选,就是深度搜索问题,从大到小遍历一次

#include<stdio.h>
int n,m;
int a[100];
void dfs(int n,int m)
{
    for(int i=n;i>=1;i--){
        a[m]=i;
        if(m>1)dfs(i-1,m-1);
        else {
            for(int i=a[0];i>=1;i--)
                printf("%d",a[i]);
            printf("\n");
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    a[0]=m;
    dfs(n,m);
    return 0;
}
问题来了:如果从小到大排列该如何做呢?

同样的方法,从小到大依次遍历,深度搜索.

#include<stdio.h>
int n,m;
int arr[100];
int vis[100];
void dfs(int cur)
{
    if(cur==m+1){
        for(int i=1;i<=m;i++)printf("%d",arr[i]);
        printf("\n");
        return;
    }
    for(int i=1;i<=n;i++){
        if(vis[i]||i<=arr[cur-1])continue;    //剪枝
        arr[cur]=i;    //选第i个数
        vis[i]=1;    //记录这个数是否被选
        dfs(cur+1);
        vis[i]=0;      //恢复现场
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        dfs(1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43328040/article/details/87271145