• 数学问题-排列组合


    1.元素序列的排列与组合

    组合序列:

    void conbination(int n,int m,int a[],int b[],const int &M){ 
        for(int j=m;j<=n;j++){
            b[m-1]=a[j-1];
            if(m>1)
                conbination(j-1,m-1,a,b,M);
            else{
                for(int i=0;i<M;i++)
                    printf("%d ",b[i]);
                printf("
    ");
            }
        }
    }

    递归图解:

    全排列:

    void swap(int *p1,int *p2){
        int t=*p1;
        *p1=*p2;
        *p2=t;
    }
    
    void full_permutation(int a[],int t,int size){
        if(t==size){
            for(int i=0;i<size;i++)
                printf("%d ",a[i]);
            printf("
    ");
        }
        else{
            for(int j=t;j<size;j++){
                swap(&a[j],&a[t]);
                full_permutation(a,t+1,size);//此处用到递归思想
                swap(&a[j],&a[t]);
            }
        }
    }

    将组合后的序列进行全排列,就得到了排列序列:

    排列序列:

    void permutation(int n,int m,int a[],int b[],const int &M){
        for(int j=m;j<=n;j++){
            b[m-1]=a[j-1];
            if(m>1)
                permutation(j-1,m-1,a,b,M);
            else{
                full_permutation(b,0,M);
            }
        }
    } 

    测试代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 100
    #define MAX 0x06FFFFFF
    #define V vector<int>
    
    using namespace std;
    
    void conbination(int n,int m,int a[],int b[],const int &M){ 
        for(int j=m;j<=n;j++){
            b[m-1]=a[j-1];
            if(m>1)
                conbination(j-1,m-1,a,b,M);
            else{
                for(int i=0;i<M;i++)
                    printf("%d ",b[i]);
                printf("
    ");
            }
        }
    }
    
    void swap(int *p1,int *p2){
        int t=*p1;
        *p1=*p2;
        *p2=t;
    }
    
    void full_permutation(int a[],int t,int size){
        if(t==size){
            for(int i=0;i<size;i++)
                printf("%d ",a[i]);
            printf("
    ");
        }
        else{
            for(int j=t;j<size;j++){
                swap(&a[j],&a[t]);
                full_permutation(a,t+1,size);//此处用到递归思想
                swap(&a[j],&a[t]);
            }
        }
    }
    
    void permutation(int n,int m,int a[],int b[],const int &M){
        for(int j=m;j<=n;j++){
            b[m-1]=a[j-1];
            if(m>1)
                permutation(j-1,m-1,a,b,M);
            else{
                full_permutation(b,0,M);
            }
        }
    } 
    
    int main(){
    int n=5,m=3;
    int a[n];int b[m];
    
    for(int i=0;i<n;i++)
    
    a[i]=i+1;
    
    const int M=m;
    puts("组合序列"); 
    conbination(n,m,a,b,M);
    puts("全排列");
    full_permutation(a,0,n);
    puts("排列序列");
    permutation(n,m,a,b,M);
        return 0;
    }
    View Code

    测试效果:

    组合序列应用实例:

    OJ链接:P1036 选数

    AC代码:

    #include <iostream>
    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <numeric>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 1010
    #define MAX (1<<30)-1
    #define V vector<int>
    
    using namespace std;
    
    int N,K; 
    int num[LEN];
    int res[LEN];
    int ans=0;
    
    bool isPrime(int x){
        if(x<2) return 0;
        for(int i=2;i<sqrt(x);i++){
            if(x%i==0) return 0;
        }
        return 1;
    }
    
    void conbination(int n,int m,int *a,int *b){//C(n,m)
        int i,j;
        for(i=m;i<=n;i++){
            res[m-1]=num[i-1];
            if(m>1)
                conbination(i-1,m-1,a,b);
            else{
                int sum=accumulate(res,res+K,0);
                if(isPrime(sum)){
    //                FF(j,K) cout<<res[j]<<' ';
    //                cout<<endl;
                    ans++;
                }
            }
        }
    }
    
    int main(){
    //    freopen("选数.txt","r",stdin);
        I("%d%d",&N,&K);
        int i;
        FF(i,N) cin>>num[i];
        conbination(N,K,num,res);
        cout<<ans<<endl;
        return 0;
    }
    View Code

    2.排列组合公式

    排列公式 P(n,m)=n!/(n-m)!

    代码:

    int P(int n,int m){
        int p=1;
        while(m){
            p*=n;
            n--;
            m--;
        }
        return p;
    } 

    代码理解:其实就是累乘,nx(n-1)x(n-2)x……x(m+1)x(m)

    --------------------------------------------------

    组合公式 C(n,m)=P(n,m)/m!=n!/[m!(n-m)!]

    int C(int n,int m){
        int i,c=1;
        i=m;
        while(i){
            c*=n;
            n--;
            i--;
        }
        while(m){
            c/=m;
            m--;
        }
        return c;
    }

    代码理解:先求出P(n,m),再计算P(n,m)/m!

  • 相关阅读:
    [转载]C# 判断字符是否中文还是英文
    [转载]C#读写配置文件(XML文件)
    [转载]C#多线程学习(一) 多线程的相关概念
    [转载]C# HashTable 遍历与排序
    [转载]C# 多选功能(checkedListBox控件)
    [转载]在C#中使用官方驱动操作MongoDB
    [转载]MongoDB开发学习(2)索引的基本操作
    公钥私钥和RSA算法
    iOS 如何在一个已经存在多个project的workspace中引入cocoapods管理第三方类库
    应用号
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8454793.html
Copyright © 2020-2023  润新知