使用 memoization 计算 python 中的二项式系数

Working out the binomial coefficient in python using memoization

我正在尝试自学动态编程并正在练习 http://www.geeksforgeeks.org/dynamic-programming-set-9-binomial-coefficient/ 中的一个问题。我首先尝试 Java 中的问题,我的代码给出了正确的结果。 Java代码:

 static int calculate(int n, int k){
    if(k == 0 || k == n)
        return 1;
    if(dp[n][k] != Integer.MAX_VALUE)
        return dp[n][k];
    else
        dp[n][k] = calculate(n - 1, k -1) + calculate(n-1, k );
    return dp[n][k];
}

然而,当我试图在 Python 中实现同样的事情时,我无法做到并且得到了奇怪的结果,例如当 n 为 5 且 k 为 2 时,我得到 13,而不是 10。我对 Python 很陌生,所以可能会遗漏一些明显的东西,但如果有人能提供帮助,我将不胜感激。 Python代码:

dp = [[-1] * 3] * 6

def calculate(n, k):
    if n == k or k == 0:
        return 1
    if dp[n][k] > 0:
        return dp[n][k]
    else:
        dp[n][k] = calculate(n-1, k-1) + calculate(n-1, k)
    return dp[n][k]

我觉得不需要这个条件if dp[n][k] > 0:.

试一试:

dp = [[-1] * 3] * 6

def calculate(n, k):
if n == k or k == 0:
    return 1
dp[n][k] = calculate(n-1, k-1) + calculate(n-1, k)
return dp[n][k]

Link : Working code

除了初始化之外,您的代码中的所有内容都是正确的。这可能是因为您可能不完全了解列表的工作原理。

看看这条语句,让我们理解它的作用:

dp = [[-1] * 3] * 6

运算符* 只是复制作为列表提供的任何内容的副本。所以所有列表本质上都是相同的并且引用一个列表。

为避免这种情况,您必须单独对其进行初始化。像这样:

dp = [[-1 for j in range(100)] for i in range(100)]

所以修改后的代码会变成这样(只是初始化方法有变化)

dp = [[-1 for j in range(100)] for i in range(100)]

def calculate(n, k):
    if n == k or k == 0:
        return 1
    if dp[n][k] > 0:
        return dp[n][k]
    else:
        dp[n][k] = calculate(n-1, k-1) + calculate(n-1, k)
    return dp[n][k]

print(calculate(5,2))

作为建议,在 python 中通常不使用列表来实现记忆,而是使用其他方法,您可能希望自己查看。