ACM求组合数的几种方法总结

1.直接计算

代码:

#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define MAXN 1000100
using namespace std;
LL n,m;
LL Cnm(LL n,LL m)//计算组合数C(n,m) 
{
	if(m>n/2)//根据组合公式,可以减少枚举量 
	m=n-m;
	LL a=1,b=1;
	for(int i=1;i<=m;i++)//顺序进行m次运算 
	{
		a*=n+1-i;//计算前i项运算结果的分子a和分母 b 
		b*=i;
		if(a%b==0)
		{
			a/=b;
			b=1;
		}
	}
	return a/b;
}
 
int main()
{
	while(cin>>n>>m)
	{
		if(n==0&&m==0)
			break;
		cout<

其实这个就可以了,

2.扩展欧几里得

LL fac[N];
void init()
{
    LL i;
    fac[0]=1;
    for (LL i = 1; i < N; i++)
	fac[i] = fac[i - 1] * i % MOD;
}
LL exgcd(LL a, LL b, LL &x, LL &y) {
    if (!b) {x = 1; y = 0; return a;}
    LL d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}
 
LL inv(LL a, LL n) {
    LL x, y;
    exgcd(a, n, x, y);
    return (x + n) % n;
}
 
LL C(LL n, LL m) {
    return fac[n] * inv(fac[m] * fac[n - m] % MOD, MOD) % MOD;
}

3.第二种费马小定理加快速幂(g^(MOD-2)=1/g%MOD,将除法问题转化为乘法)

代码:

LL da[MAXN];//G++ long long
void init()
{
    int i;
    da[0]=1;
    da[1]=1;
    for(i=2;i

4.求组合数的优化,

普通的组合数公式:C(n,m) = n!/((n-m)!*m!) = (n * n-1 * n-2 * n-3 * n-4 * n-5 * n-6 * …… * n-m) / (m * m-1 * m-2 * m-3 * m-4 * m-5 * …… * 2 * 1)

优化 :将分子和分母 的因子分别存到一个数组中 nn[]  (分子)  mm[] (分母),双重循环遍历, 进行各个因子约分,因为 组合数为一个整数 ,即N % M = 0,

所以mm[] 的元素一定可以全部约分为1,然后只需将 mm[] 中的元素相乘就行了。。

#include 
#include
#include 
using namespace std;
const int N = 10000;
int nn[N],mm[N];
int gcd(int a,int b)//  求n,m 的最大公约数
{
    return (b==0)?a:gcd(b,a%b);
}
int main()
{
    int i,j,n,m,t,h,sum,temp;
    while(cin>>n>>m&&(n||m))//  程序结束条件是 n,m 中一个为0就行,用||,我开始用&& WA了好多次,要注意
    {
        t = h = 0;
        sum = 1;
        //cout<n-m)
            m = n-m;
        for(i = n-m+1;i<=n;i++)// 分子赋值
            nn[t++] = i;
        for(i = 1;i<=m;i++)//  分母赋值
            mm[h++] = i;
        for(i = 0;i

其实有的都差不多的,

我的话最常用

#include
#include
#include
#define maxn 10010
#define ll long long
using namespace std;
 
int main()
{
    ll n,k;
    while(cin>>n>>k)
    {
        if(n==0&&k==0)
            break;
        if(n==k)
        {
            cout<

还可以的,

你可能感兴趣的:(组合数学,模板)