排列组合计数&POJ306

来源:互联网 发布:刘国梁下海经商 知乎 编辑:程序博客网 时间:2024/05/29 15:24

题意:

计算C = N! / (N-M)!M!

方法一:

#include <set>#include <cmath>#include <queue>#include <stack>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <functional>using namespace std;typedef long long LL;LL solve(LL n, LL k){    if(k >n /2)        k = n-k;    LL a = 1, b = 1;    for(int i = 1; i <= k; i++)    {        a *= (n + 1 - i);        b *= i;        if(a % b == 0)        {            a /= b;            b = 1;        }    }    return a/ b;}int main(){    //freopen("in.txt", "r", stdin);    LL n, m;    while(scanf("%I64d%I64d", &n, &m) && n)    {        printf("%I64d things taken %I64d at a time is %I64d exactly.\n", n, m, solve(n, m));    }    return 0;}

方法二:利用二项式系数公式(c[i][j] = c[i - 1][j - 1] + c[i - 1][j])

#include <set>#include <cmath>#include <queue>#include <stack>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#include <functional>using namespace std;typedef long long LL;const int maxn = 110;LL c[maxn][maxn];void init(){    for(int  i = 0; i < maxn; i++)    {        c[i][0] = 1;    }    for(int i = 1; i < maxn; i++)    {        for(int j = 1; j <= i; j++)            c[i][j] = c[i-1][j] + c[i-1][j-1];    }}int main(){    //freopen("in.txt", "r", stdin);    int n, m;    init();    while(scanf("%d%d", &n, &m) && n)    {        printf("%d things taken %d at a time is %I64d exactly.\n", n, m, c[n][m]);    }    return 0;}