如何使用 memoization 计算二项式系数?

Posted

技术标签:

【中文标题】如何使用 memoization 计算二项式系数?【英文标题】:How do I calculate binomial coefficient with memoization? 【发布时间】:2018-07-05 07:37:28 【问题描述】:

递归形式是这样的:

co:: (Int,Int) -> Int
co| k == 0 || k == n = 1
  | 0 < k, k < n = co(n-1,k-1) + co(n-1,k)
  | otherwise = 0

我如何记住,这样我就不必经常进行相同的计算?

【问题讨论】:

让我们从一个可以编译并提供正确答案的解决方案开始。您需要声明nk 修复该问题后,我认为更有效的解决方案直接来自定义:nCk = n!/((k!)(n-k!))。您可以使用product 来计算阶乘,这样就不需要记忆了。 您可以将值存储在盒装数据结构中,例如地图或数组。要么更新并将每个新值插入到映射中,将更新后的映射作为程序状态传递,要么使用惰性创建一个充满 thunk 的结构,它只会在需要时计算一次值。 【参考方案1】:

如果您感觉清醒并希望有人理解您的程序,以下是实现二项式系数的方法:

--| computes the binomial coefficient n choose k = n!/k!(n-k)!
binom n k = product [max (k+1) (n-k+1) .. n] `div` product [1 .. min k (n-k)]

下面是一个简单的方法来记住这样的两个参数的函数:

binom n k = (vals !! n) !! k where
  vals = 1 : [ 1 : [if k == n
                    then 1
                    else binom (n-1) (k-1) + binom (n-1) k
                   | k <- [1..n]]
             | n <- [1..]]

【讨论】:

以上是关于如何使用 memoization 计算二项式系数?的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中计算 *integer* 二项式系数

使用动态规划计算二项式系数

以二进制计算二项式系数

二项式系数和公式

计算具有大二项式系数的总和

UVa 10883 超级平均数(二项式系数+对数计算)