C++ 实现计算组合数(一乘一除法附讲解)

Cnm = n! /(m! * (n - m)!)

此时 n! 可以和 (n - m)! 约去得到 (n - m + 1) ~ n ,共 m 个数

而剩下的 1 / m! 也是 m 个数,

   所以可以在代码中通过m个循环反复先乘后除缩小数据规模

long long C(int n, int m){
    if(n == m || m == 0){
        return 1;
    }
    //替换为等价值中较小的,减少循环次数
    m = min(m, n - m);
    long long res = 1;
    for(int i = 1; i <= m; ++i){
        res = res * (n - m + i) / i;
        // res *= (n - m + i) / i 这种写法会先计算除法,可能损失数据造成计算错误
    }
    return res;
}

在这个过程中总是能除尽的,因为当除数取到 i 时,被除数已经有连续的 i 个数相乘,连续的i个数中必然有能整除 i 的。如当 i 取 3 时, 已经有连续的 3 个数如 77 78 79 ,有78可以整除,即使78 提前被 2 除了也不要紧,因为 3 是 78 的因数,可看作 3 * 26 = 78, 26 被 2 除为 14 不会引起 3 这个因数的损失。

 参考:

C++求解组合数的具体实现

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值