求组合数(四种方法)

您所在的位置:网站首页 常见阶乘公式 求组合数(四种方法)

求组合数(四种方法)

2023-06-13 14:16| 来源: 网络整理| 查看: 265

文章目录 求组合数(四种方法)递推(杨辉三角)快速幂+乘法逆元卢卡斯定理高精度组合数

求组合数(四种方法)

文章首发于我的个人博客:欢迎大佬们来逛逛

递推(杨辉三角)

对于求一个数字的组合数: C n m C_{n}^{m} Cnm​ 可以分解为这两种形式:

C n − 1 m − 1 C_{n-1}^{m-1} Cn−1m−1​ :选择当前数 C n − 1 m C_{n-1}^{m} Cn−1m​ :不选择当前数

因此就得到了递推公式:

C n m = C n − 1 m − 1 + C n − 1 m C_{n}^{m}=C_{n-1}^{m-1}+C_{n-1}^{m} Cnm​=Cn−1m−1​+Cn−1m​

for (int i=0;i if (j==0){ dp[i][j]=1; //n个数中取0个,默认为1 } else{ dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%p; } } }

由于需要用到二重循环,因此此方法适用的范围是: n , m < = 1 0 4 n,m //得到C(n,m)的组合数答案 return f[n]*g[m]*g[n-m]%p; }

容易得知此方法计算组合数的使用范围大概是: n , m < = 1 0 7 n,m //得到C(n,m)的组合数答案 return f[n]*g[m]*g[n-m]%p; } ... int lucas(int n,int m){ if (m==0){ return 1; } return lucas(n/p,m/p)*get(n%p,m%p)%p; }

此方法使用范围(大概): n , m < = 1 0 18 , p < = 1 0 6 n,m cnt+=n/p; n/=p; } return cnt; } int how(int n,int m,int p){ return get(n,p)-get(n-m,p)-get(m,p); } void mul(int s,int& len){ //高精度乘法 int t=0; for(int i=0;i C[len++]=t%10; t/=10; } } signed main(){ //求C(n,m) std::cin>>n>>m; init(); int len=1; C[0]=1; for (int i=1;i mul(x,len); } } for (int i=0;i



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3