我必须实现一个问题,该问题计算来自一组n个元素的m个元素的组合和多个集合。 它们的公式如下:
问题在于,使用阶乘很容易溢出,所以基本上解决这个问题的解决方案是什么?
由于它是TopCoder中问题的子问题,我有以下约束:
1)程序必须用C ++编写。
2)我无法加载外部库。
答案 0 :(得分:5)
你真的不需要直接计算n!
,这可能很容易被溢出。从那以后
C(n,m) = C(n-1, m-1) + C(n-1,m)
C(n,0) = C(n,n) =1
您可以构建一个大小为(n+1,m+1)
的表,并使用动态编程以自下而上的方式构建表。
算法伪代码可能如下所示:
for i ← 0 to n do // fill out the table row wise
for j = 0 to min(i, m) do
if j==0 or j==i then C[i, j] ← 1
else C[i, j] ← C[i-1, j-1] + C[i-1, j]
return C[n, m]
如果你声明c(n,m)
是长双,而n不是那么大,这种方式应该有效。否则,您需要定义自己的BigInteger类以避免溢出并定义+
运算符如何为BigIntegers工作,BigIntegers通常表示为字符数组或字符串。
答案 1 :(得分:0)
因子是非常大的数字(它们不适合64位字)。因此,您需要使用bignums(任意精度算术)来完全计算它们。考虑将GMPlib用于此目的(或者使用语言和实现中的代码,例如带有SBCL的Common Lisp,它可以原生地提供它们)
答案 2 :(得分:0)
不使用递归方法计算可能导致堆栈溢出的阶乘,而是使用迭代方法!即使是较大的数字,这也可以为您节省溢出。