• 排列组合生成算法


     

    r排列生成:

    gen 递归层数d表示正在生成第d个元素。

    vis记录是否出现过。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    
    int n, r;
    int A[50], vis[50];//记录第i个元素是否生成过
    int cnt;
    int rer;
    
    void output(int r)
    {
        for(int i = 0; i < r; i++) printf("%d ", A[i]);
        printf("
    ");
    }
    
    //生成P(n, r), r==n时,生成全排列
    //递归层数d代表正在生成第d个位置元素
    void gen(int d) {
            rer++;
      if(d == r ) {
              cnt++;
              output(r);
      }
      else for(int i = 0; i < n; i++)
        if(!vis[i]) {
          A[d] = i;
          vis[i] = 1;
          gen(d+1);
          vis[i] = 0;
        }
    }
    
    void gen1(int d)
    {
            for(int i=0;i<n;i++)
            {
                    if(!vis[i])
                    {
                            vis[i]=1;
                            A[d]=i;
                            if(d==r-1)
                                    output(r);
                            else
                                    gen1(d+1);
                            vis[i]=0;
                    }
            }
    }
    
    int main() {
      scanf("%d%d", &n, &r);
      memset(vis, 0, sizeof(vis));
      gen(0);
      gen1(0);
      //printf("%d
    ", cnt);
      //printf("%d
    ", rer);
      return 0;
    }

    r组合生成,C(n,r) 对应r!个P(n,r),所以我们按照元素递增的方式来生成相应位置的元素,就能产生C(n,r)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    
    int n, r;
    int A[50], vis[50];//记录第i个元素是否生成过
    int cnt;
    int rer;
    
    void output(int r)
    {
        for(int i = 0; i < r; i++) printf("%d ", A[i]);
        printf("
    ");
    }
    
    //生成C(n, r), 
    //递归层数d代表正在生成第d个位置元素
    void gen(int d, int from) {
        rer++;
      if(d == r ) {
          cnt++;
          output(r);
      }   
      else for(int i = from; i < n; i++)
        if(!vis[i]) {
          A[d] = i; 
          vis[i] = 1;
          gen(d+1, i+1);
          vis[i] = 0;
        } 
    }   
    
    void gen1(int d, int from)
    {
        for(int i=from;i<n;i++)
        {
            if(!vis[i])
            {
                vis[i]=1;
                A[d]=i;
                if(d==r-1)
                    output(r);
                else
                    gen1(d+1, i+1);
                vis[i]=0;
            }
        }
    }
    
    int main() {
      scanf("%d%d", &n, &r);
      memset(vis, 0, sizeof(vis));
      //gen(0, 0);
      gen1(0, 0);
      //printf("%d
    ", cnt);
      //printf("%d
    ", rer);
      return 0;
    }

    参考:程序设计中的组合数学

  • 相关阅读:
    Search Insert Position(二分查找)
    c++基础题
    Divide Two Integers(模拟计算机除法)
    Swap Nodes in Pairs(链表操作)
    Letter Combinations of a Phone Number(带for循环的DFS,组合问题,递归总结)
    进程和程序的区别
    Add Two Numbers(链表)
    Longest Substring Without Repeating Characters
    02.友盟项目--原始日志数据生成
    01.友盟项目--nginx服务器配置
  • 原文地址:https://www.cnblogs.com/cute/p/3701613.html
Copyright © 2020-2023  润新知