大 n 表示阶乘

large n for factorials

本文关键字:阶乘 表示      更新时间:2023-10-16

我正在尝试解决一个非常简单的任务,即在 1<=n,k<=50 时找到 nCk。我似乎找不到一种方法来输出非常大的数字的结果,例如 50 in C++。我的算法仅适用于小整数值。

我为 nCk 公式实现了一个阶乘函数,但我找不到一种方法来解决更大的数字和 1s 中的此类任务。

#include <iostream>
using namespace std;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int i, n, k;
long long res, num, den;
res = num = den = 1;
cin >> n >> k;
if (n < k) {
cout << 0;
return 0;
}
if (n == k || k == 0) {
cout << 1;
return 0;
}
for (i = 1; i <= k; i++) {
if ((n - i + 1) % i == 0) {
res = res * ((n - i + 1) / i);
}
else {
num *= (n - i + 1);
den *= i;
}   
}
cout << (res*num)/den;
return 0;
}

这个解决方案需要一些数学而不是编程(来解决溢出问题(。

你有:

n! / (k! * (n - k)!)

您可以通过扩展它轻松消除公共因素。例如:

n = 8, k = 3

8*7*6*5*4*3*2*1 / ((3*2*1) * (5*4*3*2*1))

扩展到

8*7*6*5*4*3*2*1 / 3*2*1*5*4*3*2*1

请注意我们如何通过除法规则从两者中删除5*4*3*2*1?然后我们得到

8*7*6 / 3*2*1

这将更容易计算。

最终,如果你继续变大,你无论如何都会遇到问题,所以你可能需要研究Boost的多精度

您当前的公式是

binom(n, k) = n! / (n - k)!k!

这个公式对数学没问题,但对计算不行。 简化它:

binom(n, k) = n(n - 1)(n - 2) ... (n - k + 1) / k!

涉及的术语较少。 另请注意

binom(n, k) = binom(n, n - k)

如果k > n / 2,可以用作优化。

此外,如果数字太大,则需要使用 GMP 等多精度库。