avatar
fireworks99
keep hungry keep foolish

组合数与第二类斯特林数

求解组合数 C(n,m)

暂时有三种方法:

1.存在数组里递归求解

2.较为生猛地求解(连乘连除)

3.改良版(乘一次除一次)

Code(存于数组)

long long c[105][105];
void combine_init()
{
    memset(c, 0, sizeof(c));
    c[0][0] = 1;
    for(int i = 1; i <= 105; ++i)
    {
        c[i][0] = c[i][i] = 1;
        c[i][1] = i;
        for(int j = 1; j < i; ++j)
            if(c[i][j] == 0)
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]);/// % mod
    }
}

Code(连乘连除)

long long violent_combine(long long n,long long m)
{
    if(m < n - m)
        m = n - m;///取个较大值
    long long ans = 1;
    for(long long i = m + 1; i <= n; ++i)/// fac(n) / fac(m)
        ans *= i;
    for(long long i = 1; i <= n - m; ++i)/// fac(n - m)
        ans /= i;
    return ans;
}

Code(乘除共进)

long long combine(long long a, long long b)
{
    if(b > a - b)
        b = a - b;///取个较小值
    long long ans = 1;
    for(int i = 1; i <= b; ++i)
    {
        ans *= (a + 1 - i);/// fac(a) / fac(a - b)
        ans /= i;          /// fac(b)
    }
    return ans;
}

update 第二类斯特林数

c[n][m]把n个元素分到m个非空且不可区分的集合中去

memset(c, 0, sizeof(c));
    c[1][1] = 1;
    for(int i = 2; i<= 105; ++i)
        for(int j = 1; j <= i; ++j)
            if(c[i][j] == 0)
                c[i][j] = (c[i - 1][j] * j + c[i - 1][j - 1]) % mod;
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy