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

时间:2017-09-13 11:54:06

标签: python-3.x dynamic-programming 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]

2 个答案:

答案 0 :(得分:1)

我认为不需要这种情况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]

链接:Working code

答案 1 :(得分:0)

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

请查看此声明并了解它的作用:

USE AdventureWorks2014;
GO

-- Run a stored procedure or query
EXEC dbo.uspGetEmployeeManagers 9;

-- Find the plan handle for that query 
-- OPTION (RECOMPILE) keeps this query from going into the plan cache
SELECT cp.plan_handle, cp.objtype, cp.usecounts, 
DB_NAME(st.dbid) AS [DatabaseName]
FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st 
WHERE OBJECT_NAME (st.objectid)
LIKE N'%uspGetEmployeeManagers%' OPTION (RECOMPILE); 

-- Remove the specific query plan from the cache using the plan handle from the above query 
DBCC FREEPROCCACHE (0x050011007A2CC30E204991F30200000001000000000000000000000000000000000000000000000000000000);

运营商dp = [[-1] * 3] * 6 只复制以列表形式提供的任何副本。所以所有列表基本相同并引用一个列表。

要避免这种情况,您必须单独初始化它。这样的事情:

*

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

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

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