zoukankan      html  css  js  c++  java
  • 组合数C(n,m)的四种求解方法

    转自:文章

    1、暴力求解

    C(n,m)=n*(n-1)*...*(n-m+1)/m!,(n<=15);

    int CF(int n,int m)
    {
        int ans=1,i,j;
        for(i=n;i>=n-m+1;i--)
        ans*=i;
        for(i=m;i>=2;i--) 
        ans/=i;
        return ans;
    }

    2、打表

    C(n,m)=C(n-1,m-1)+C(n-1,m),(n<=10000);

    const int maxn = 10010;
    const int MOD = 100007;
    void CF(int n,int m)
    {
        int i,j;
        for(i=0;i<=maxn;i++)
        {
            c[0][i]=0;c[i][0]=1;
        }
        for(i=1;i<=maxn;i++)
            for(j=1;j<=maxn;j++)
            c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
    }

    3、质因数分解

    C(n,m)=n!/(m!*(n-m)!),C(n,m)=p1a1-b1-c1p2a2-b2-c2…pkak-bk-ck,(n<=10000000)

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int MOD = 100007;
    const int maxn = 1000001;
    bool a[maxn]={false};
    vector <int> prim_produce() //生成素数序列 
    {
        vector <int> vc;
        vc.push_back(2);
        int i,j;
        for(i=3;i*i<=maxn;i+=2)
        {
            if(!a[i])
            {
                vc.push_back(i);
                for(j=i*i;j<=maxn;j+=i)
                {
                    a[j]=true;
                }
            }
        }
        while(i<maxn)
        {
            if(!a[i]) vc.push_back(i);
            i+=2;
        }
        return vc;
    }
    //计算n!素数p的指数 
    int cal(int x,int p)
    {
        int ans=0;
        long long re=p;
        while(x>=re)
        {
            ans+=x/re;
            re*=p;
        }
        return ans; 
    }
    
    int Pow(long long n,int k) //二分求n的k次方 
    {
        long long ans=1;
        while(k)
        {
            if(k&1) ans=ans*n%MOD;
            n=(n*n)%MOD;
            k>>=1;
        }
        return ans;
    }
    int comb(int n,int m) //计算公式 
    {
        vector <int> prim=prim_produce();
        long long ans=1;
        int num;
        for(int i=0;i<prim.size()&&prim[i]<=n;i++)
        {
            num=cal(n,prim[i])-cal(m,prim[i])-cal(n-m,prim[i]);
            ans=(ans*Pow(prim[i],num))%MOD;
        }
        return ans;
    }
    int main(void)
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            printf("%d
    ",comb(n,m));
        }
        return 0;
    }
    View Code

    4、Lucas定理

    将m,n化为p进制,有:C(n,m)=C(n0,m0)*C(n1,m1)...(mod p),算一个不是很大的C(n,m)%p,p为素数,化为线性同余方程,用扩展的欧几里德定理求解,n在int范围内,修改一下可以满足long long范围内。

     

    #include <stdio.h>
    const int M = 2013;
    int ff[M+5];  //打表,记录n!,避免重复计算
     
    //求最大公因数
    int gcd(int a,int b)
    {
        if(b==0)
            return a;
        else
            return gcd(b,a%b);
    }
     
    //解线性同余方程,扩展欧几里德定理
    int x,y;
    void Extended_gcd(int a,int b)
    {
        if(b==0)
        {
            x=1;
            y=0;
        }
        else
        {
            Extended_gcd(b,a%b);
            long t=x;
            x=y;
            y=t-(a/b)*y;
        }
    }
     
    //计算不大的C(n,m)
    int C(int a,int b)
    {
        if(b>a)
            return 0;
        b=(ff[a-b]*ff[b])%M;
        a=ff[a];
        int c=gcd(a,b);
        a/=c;
        b/=c;
        Extended_gcd(b,M);
        x=(x+M)%M;
        x=(x*a)%M;
        return x;
    }
     
    //Lucas定理
    int Combination(int n, int m)
    {
        int ans=1;
        int a,b;
        while(m||n)
        {
            a=n%M;
            b=m%M;
            n/=M;
            m/=M;
            ans=(ans*C(a,b))%M;
        }
        return ans;
    }
     
    int main()
    {
        int i,m,n;
        ff[0]=1;
        for(i=1; i<=M; i++) //预计算n!
            ff[i]=(ff[i-1]*i)%M;
        while(~scanf("%d%d",&n, &m))
        {
            printf("%d
    ",Combination(n,m));
        }
        return 0;
    }
    View Code

     

  • 相关阅读:
    序列模型
    conda安装库时报错Solving environment: failed with initial frozen solve. Retrying with flexible solve.
    OverflowError: mktime argument out of range问题
    Supervised ML-1
    CKE(Collaborative Knowledge Base Embedding for Recommender Systems)笔记
    Word2vec学习
    BERT
    DeText: A Deep Text Ranking Framework with BERT论文笔记
    解决Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.(IDEA连接mysql数据库)
    django-settings配置介绍
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10178921.html
Copyright © 2011-2022 走看看