转载自

组合c(m,n)的计算方法

   问题:求解组合数C(n,m),即从n个相同物品中取出m个的方案数,由于结果可能非常大,对结果模10007即可。

共四种方案。ps:注意使用限制。

方案1:

暴力求解,C(n,m)=n*(n-1)*...*(n-m+1)/m!,n<=15

int Combination(int n, int m)
{ const int M = 10007; int ans = 1; for(int i=n; i>=(n-m+1); --i) ans *= i; while(m) ans /= m--; return ans % M;
} int Combination(int n, int m)
{const int M = 10007;int ans = 1;for(int i=n; i>=(n-m+1); --i)ans *= i;while(m)ans /= m--;return ans % M;
}

方案2:

打表,C(n,m)=C(n-1,m-1)+C(n-1,m),n<=10,000

const int M = 10007;
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];
} const int M = 10007;
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];
}

方案3:

质因数分解,C(n,m)=n!/(m!*(n-m)!),C(n,m)=p1a1-b1-c1p2a2-b2-c2…pkak-bk-ck,n<=10,000,000

#include <cstdio>
const int maxn=1000000;
#include <vector>
using namespace std;
bool arr[maxn+1]={false};
vector<int> produce_prim_number()
{ vector<int> prim; prim.push_back(2); int i,j; for(i=3;i*i<=maxn;i+=2) { if(!arr[i]) { prim.push_back(i); for(j=i*i;j<=maxn;j+=i) arr[j]=true; } } while(i<maxn) { if(!arr[i]) prim.push_back(i); i+=2; } return prim;
}
//计算n!中素数因子p的指数
int cal(int x,int p)
{ int ans=0; long long rec=p; while(x>=rec) { ans+=x/rec; rec*=p; } return ans;
}
//计算n的k次方对m取模,二分法
int pow(long long n,int k,int M)
{ long long ans=1; while(k) { if(k&1) { ans=(ans*n)%M; } n=(n*n)%M; k>>=1; } return ans;
}
//计算C(n,m)
int combination(int n,int m)
{ const int M=10007; vector<int> prim=produce_prim_number(); 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,M))%M; } return ans;
}
int main()
{ int m,n; while(~scanf("%d%d",&m,&n),m&&n) { printf("%d\n",combination(m,n)); } return 0;
} 

方案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;elsereturn 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\n",Combination(n,m));}return 0;
}

组合数C(n,m)的四种计算方法相关推荐

  1. 组合数C(m,n)的四种求法

    文章目录 递推.杨辉三角 乘法逆元.费马小定理 Lucas定理 欧拉筛.阶乘的质因子.高精度 递推.杨辉三角 AcW885. 求组合数 I #include<bits/stdc++.h> ...

  2. 如何理解LTV(单个用户整个生命周期价值)的5种计算方法?

    前言:本文内容以游戏产品为基础进行讲解,内容为LTV的5种计算方法. 定义:LTV值单个用户整个生命周期所产生的价值. 说明:在谈论LTV的计算方法时,容易混淆的点:指标限定的时间范围.LTV的每种计 ...

  3. 组合数c(n,m)计算的四种方法

    转载自 组合c(m,n)的计算方法    问题:求解组合数C(n,m),即从n个相同物品中取出m个的方案数,由于结果可能非常大,对结果模10007即可. 共四种方案.ps:注意使用限制. 方案1: 暴 ...

  4. 行列式的计算方法(含四种,看完就会!)

    行列式的计算方法 前言 一.对角线法 二.代数余子式法 三.等价转化法 四.逆序数法 总结 前言 提示:本文主要讲述行列式的求解方法,所以本文侧重于方法的讲解,而并非推导.主要思路为从三阶行列式举例, ...

  5. 【算法】计算组合数的四种常用方法

    [算法]计算组合数的四种常用方法 算法一:Cab=Ca−1b−1+Ca−1bC_{a}^{b}=C_{a-1}^{b-1}+C_{a-1}^{b}Cab​=Ca−1b−1​+Ca−1b​ 解析: Ca ...

  6. 组合数的几种计算方法

    组合数一种是OI中比较常用的知识 除了实际的分析之外,我们要考虑的,就是如何快速计算组合数 下面介绍几种常用的计算组合数的方法 朴素公式法 顾名思义,直接套公式 int C(int n,int m){ ...

  7. 【深度学习】深度学习中模型计算量(FLOPs)和参数量(Params)等的理解以及四种在python应用的计算方法总结

    接下来要分别概述以下内容: 1 首先什么是参数量,什么是计算量 2 如何计算 参数量,如何统计 计算量 3 换算参数量,把他换算成我们常用的单位,比如:mb 4 对于各个经典网络,论述他们是计算量大还 ...

  8. 概率的四种定义及公理化定义产生

    本博文源于北京理工大学的<概率论与数理统计>.讨论四种定义分别是:古典定义.几何定义.频率定义.公理化定义. 概率的四种定义及公理化定义产生 古典概型 概率的古典定义 古典概型的计算方法 ...

  9. 计算机网络中的时延有哪几部分,计算机网络中的四种延迟分别是什么?

    计算机网络中的四种延迟分别是:节点处理延迟 .排队延迟.发送延迟.传播延迟. 1.节点处理延迟 数据更改在一个服务器上完成与该更改出现在另一个服务器上之间所用的时间(例如在发布服务器上进行更改和该更改 ...

最新文章

  1. ROM、RAM、IROM、IRAM、DRAM、SRAM、Flash介绍
  2. 一个链接orcal的标准链接方法
  3. 最新研究 | 人类大脑皮质对有声调和非有声调语言的音高编码
  4. Oracle WebCenter 11g 快速开发指南--翻译(一)
  5. Kali 找回root 密码的操作步骤
  6. android 能自动选择的listview,Android ListView多选模式
  7. codeforces 15C. Industrial Nim
  8. linux系统下的“静态库和动态库”专题之二:库的创建和使用
  9. 怎样用计算机添加文章标题,计算机论文题目怎么定-易指做帮写网
  10. 【华为大咖分享】5.交付在云端-全云DevOps研发实践(后附PPT下载地址)
  11. AIX LV删除后,ORACLE数据库文件全部恢复成功
  12. kali 创建php可执行文件_利用树莓派在kali环境下搭建Web环境(Apache+Php7.3+Mysql)...
  13. 一些基础的MySQL数据库操作语句
  14. 高级shell编程讲解
  15. 一加8t(oneplus 8t)通过9008救砖
  16. [SSL_CHX][2021-08-19]转二进制
  17. Vue项目引入icon图标的两种方法
  18. mysql 表名 下划线_我们可以在MySQL表名中加下划线吗?
  19. 宇宙最强vscode教程
  20. OpenPAI1.3.0 部署

热门文章

  1. 如何写出一篇好文章——不动笔就能学会写文章的训练法
  2. 前端Vue项目调用页面web3.js:连接metaMask钱包,(查询钱包ETH余额,查询代币余额,ETH转账,代币转账,代币授权,查询授权数量,计算价格)等功能
  3. Android 酒店客房管理简单小程序
  4. JAVA射线_射线法 - 萌德真帅 - 博客园
  5. 钟汉良日记:凡夫俗子一定要眼见为实,菩萨才能见因知果!
  6. “21 天好习惯”第一期-6
  7. opencv下载过慢的问题
  8. 在否定句和疑问句使用have动词_26
  9. 英语练习day2 一般,否定疑问句,现表将来
  10. type-c耳机方案