简体   繁体   中英

Top-down Dynamic Programming in python

I am trying to solve the following problem using Python 3: https://www.hackerrank.com/contests/projecteuler/challenges/euler015 .

Following is my code:

def dp(x,y):
    global MEMO,N,M
    if x>N or y>M:return 0
    if x==N and y==M:
        return 1
    if MEMO[x][y]!=-1:return MEMO[x][y]
    MEMO[x][y]=(dp(x+1,y)+dp(x,y+1))%1000000007
    return MEMO[x][y]

MEMO=[[-1]]
N=0
M=0
tc=int(input())
while tc:
    tc-=1
    N,M=map(int,input().split())
    MEMO=[[-1]*(M+1)]*(N+1)
    print(dp(0,0))

However, for the given test case, it gives answer 3(not 6). I think it has something to do with the local/global scoping of variables. Where am I going wrong?

MEMO=[[-1]*(M+1)]*(N+1) replicates the list [-1] M+1 times, but it does so with the same instance of the list. Print it out to see what's going on:

>>> M=2
>>> N=2
>>> MEMO=[[-1]*(M+1)]*(N+1)
>>> MEMO[0].append(1)
>>> MEMO
[[-1, -1, -1, 1], [-1, -1, -1, 1], [-1, -1, -1, 1]]

See how they were all mutated by the append method? That's because they're literally the same list. This problem is known as aliasing .

You can fix this by constructing a new list each time:

MEMO=[[-1 for x in xrange(M+1)] for x in xrange(N+1)]

This:

MEMO=[[-1]*(M+1)]*(N+1)

makes MEMO contain (N+1) references to the same list. It's probably not what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM