C++ 计算大组合

C++ 计算大组合,c++,algorithm,permutation,dynamic-programming,combinatorics,C++,Algorithm,Permutation,Dynamic Programming,Combinatorics,您将如何计算组合,例如(100000选择50000) 到目前为止,我尝试了三种不同的方法,但由于明显的原因,每种方法都失败了: 1) 动态规划-数组的大小变得如此荒谬,以至于无法区分错误 unsigned long long int grid[p+1][q+1]; //Initialise x boundary conditions for (long int i = 0; i < q; ++i) { grid[p][i] = 1; } //Initialise y boundar

您将如何计算组合,例如(100000选择50000)

到目前为止,我尝试了三种不同的方法,但由于明显的原因,每种方法都失败了:

1) 动态规划-数组的大小变得如此荒谬,以至于无法区分错误

unsigned long long int grid[p+1][q+1];

//Initialise x boundary conditions
for (long int i = 0; i < q; ++i) {
  grid[p][i] = 1;
}

//Initialise y boundary conditions
for (long int i = 0; i < p; ++i) {
  grid[i][q] = 1;
}


for (long int i = p - 1; i >= 0; --i) {
  for (long int j = q - 1; j >= 0; --j) {
     grid[i][j] = grid[i+1][j] + grid[i][j+1];
   }
}
3) 乘法公式-我无法存储值,它们太大了

const int gridSize = 100000; //say 100,000
unsigned long long int paths = 1;

for (int i = 0; i < gridSize; i++) {
    paths *= (2 * gridSize) - i;
    paths /= i + 1;
}

// code from (http://www.mathblog.dk/project-euler-15/)
const int gridSize=100000//10万吧
无符号长整型路径=1;
对于(int i=0;i
如果它有助于上下文,则其目的是解决“通过m×n网格有多少条路径”的大输入问题。也许我没能解决这个问题?

C(100000,50000)是一个巨大的数字,有30101个小数位:

显然,
unsigned long
不足以存储它。您需要一些任意大整数库,如:


否则,乘法公式就足够了。

这里有一个递归公式可能会有所帮助:-

NCk=(N-1)C(k-1)*N/k

首先对(N-1)C(K-1)使用递归调用,然后对结果计算NCk

由于您的人数将非常多,请使用以下备选方案之一

  • GMP
  • 使用您自己的实现,您可以将数字存储为数组中的二进制位序列,并使用booth的乘法算法 移位和减法进行除法运算
  • “你将如何计算…”在很大程度上取决于期望的精度。精确的结果只能用任意精度数字(如GMP)计算,但很可能您并不真正需要精确的结果

    在这种情况下,我将对阶乘()使用斯特林近似,并使用双精度进行计算。展开式中的求和数可用于调节误差。维基百科页面也会给你一个错误估计

    const int gridSize = 100000; //say 100,000
    unsigned long long int paths = 1;
    
    for (int i = 0; i < gridSize; i++) {
        paths *= (2 * gridSize) - i;
        paths /= i + 1;
    }
    
    // code from (http://www.mathblog.dk/project-euler-15/)