#include using namespace std; typedef long long LL; //求组合数公式原始方法 //优点:从定义出发,易理解 //缺点:过早溢出,比如 C1(17,54)得到了负数 LL C1(int n, int m) { if (m < n - m) m = n - m; //此处加了一个小优化,使用了公式2 LL ans = 1; for (int i = m + 1; i <= n; i++) ans *= i; for (int i = 1; i <= n - m; i++) ans /= i; return ans; } //求组合数的优化后办法 //优点:从1开始除和乘,可以防止过早溢出和除法除不尽 LL C2(int n, int m) { LL sum = 1; for (int i = 1; i <= m; i++) sum = sum * (n - m + i) / i; return sum; } int main() { printf("%lld\n", C1(54, 17)); printf("%lld\n", C2(54, 17)); return 0; }