zoukankan      html  css  js  c++  java
  • 排列组合生成算法

     

    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;
    }

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

  • 相关阅读:
    1093 Count PAT's(25 分)
    1089 Insert or Merge(25 分)
    1088 Rational Arithmetic(20 分)
    1081 Rational Sum(20 分)
    1069 The Black Hole of Numbers(20 分)
    1059 Prime Factors(25 分)
    1050 String Subtraction (20)
    根据生日计算员工年龄
    动态获取当前日期和时间
    对计数结果进行4舍5入
  • 原文地址:https://www.cnblogs.com/cute/p/3701613.html
Copyright © 2011-2022 走看看