组合数模版 整理

来源:互联网 发布:tsis交通仿真软件 编辑:程序博客网 时间:2024/05/17 07:52

第一个转自:九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/12318011

组合数:

公式递推代码

C(n, m)  = C(n -1, m - 1) + C(n - 1, m)

 

const int M = 10007; //注意M是 取模const int MAXN = 1000;int C[MAXN+1][MAXN+1];void Initial(){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]) % M;}}int Combination(int n, int m){return C[n][m];}


上面的很耗费空间,其实C(5,3) == C(5,2),C(5,1) == C(5,4)所以这样可以构造省空间型


int c[5000 + 5][2500 + 5];void C() { for(int i=0; i<=5000; ++i) {c[i][0] = 1;}c[1][1] = 1;for(int i=2; i<=5000; ++i) for(int j=1; j<=i/2; ++j)c[i][j] = (c[i-1][min(j - 1,i - j)] + c[i-1][min(j,i - j - 1)]) % MOD;}



直接求函数型,因为除法对取模有影响,但是可以转为乘法,也就是乘法逆元

来自:http://www.cnblogs.com/woaishizhan/archive/2013/08/13/3254590.html


ll exgcd(ll a, ll b, ll &x, ll &y)  {if(!b) {x = 1; y = 0;return a;}ll r = exgcd(b, a%b, y, x);y -= a/b*x;return r;}ll inv(ll a, ll m){ll x,y,gcd = exgcd(a, m, x, y);if(x < 0)  x += m;return x;}ll C(ll n,ll m) {ll ans = 1;for(int i=1;i<=m;i++)ans = ((ans * inv(i,MOD))%MOD * (n - i + 1))%MOD;return ans;}

跟上一个差不多的,看N,M的值分别来行事而已


ll exgcd(ll a, ll b, ll &x, ll &y)  {if(!b) {x = 1; y = 0;return a;}ll r = exgcd(b, a%b, y, x);y -= a/b*x;return r;}ll inv(ll a, ll m){ll x,y,gcd = exgcd(a, m, x, y);if(x < 0)  x += m;return x;}ll C(ll n,ll m)//计算组合数C(n,m){    ll t1=1,t2=1;    for(LL i=n;i>m;i--)    {        t1=(t1*i)%MOD;        t2=(t2*(i-m))%MOD;    }    return t1*inv(t2,MOD)%MOD;}


lucs定理模版,用于求 C(n,m)%p,p为素数

http://baike.baidu.com/link?url=apwqocXofh-46Q0Dlcv7ooimiks-aRW9we5-gq9G7Oblu3P-HbvXfHXmRH-3inaIpXaHzvWL4dY5mOZspu31Na

int inv(int a) {return a == 1 ? 1 : (ll)(MOD - MOD / a) * inv(MOD % a) % MOD;}ll C(ll n,ll m){    if(m < 0)return 0;    if(n < m)return 0;    if(m > n-m) m = n-m;        ll up = 1, down = 1;    for(ll i = 0 ; i < m ; i ++){        up = up * (n-i) % MOD;        down = down * (i+1) % MOD;    }    return up * inv(down) % MOD;}ll lucas(ll n,ll m,ll p){    ll ret = 1;    while(n && m){        ll a = n % p,b = m % p;        if(a < b)return 0;        ret = ret * C(a,b) % p;        n /= p;        m /= p;    }    return ret;}


0 0
原创粉丝点击