我在Project Euler偶然发现了一个问题,https://projecteuler.net/problem=15 。我通过组合学解决了这个问题,但是想知道是否存在针对这个问题的动态编程解决方案或整体上的这类问题。并且说网格的一些正方形被取消 - 是否可以导航?我正在使用Python。我该怎么办?任何提示都表示赞赏。提前谢谢。
答案 0 :(得分:1)
你可以做一个简单的回溯并探索这样的隐式图:(评论解释了大部分内容)
def explore(r, c, n, memo):
"""
explore right and down from position (r,c)
report a rout once position (n,n) is reached
memo is a matrix which saves how many routes exists from each position to (n,n)
"""
if r == n and c == n:
# one path has been found
return 1
elif r > n or c > n:
# crossing the border, go back
return 0
if memo[r][c] is not None:
return memo[r][c]
a= explore(r+1, c, n, memo) #move down
b= explore(r, c+1, n, memo) #move right
# return total paths found from this (r,c) position
memo[r][c]= a + b
return a+b
if __name__ == '__main__':
n= 20
memo = [[None] * (n+1) for _ in range(n+1)]
paths = explore(0, 0, n, memo)
print(paths)
答案 1 :(得分:1)
最简单的使用python的内置memoization util https://www.tutorialspoint.com/cprogramming/c_pointers.htm。您可以将缺失的方块编码为frozenset
(可清除)缺少的网格点(对):
from functools import lru_cache
@lru_cache(None)
def paths(m, n, missing=None):
missing = missing or frozenset()
if (m, n) in missing:
return 0
if (m, n) == (0, 0):
return 1
over = paths(m, n-1, missing=missing) if n else 0
down = paths(m-1, n, missing=missing) if m else 0
return over + down
>>> paths(2, 2)
6
# middle grid point missing: only two paths
>>> paths(2, 2, frozenset([(1, 1)]))
2
>>> paths(20, 20)
137846528820
答案 2 :(得分:0)
还有一个数学解决方案(可能就是你使用过的):
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
def paths(w, h):
return factorial(w + h) / (factorial(w) * factorial(h))
这是有效的,因为路径的数量与选择在w + h
步骤上向右或向下移动的方式相同,在这些步骤中,您向右移动w次,等于w + h choose w
,或(w + h)! / (w! * h!)
。
缺少网格方块,我认为有一个组合解决方案,但如果有很多缺失的方块,它会很慢,所以动态编程可能会更好。
例如,以下应该工作:
missing = [
[0, 1],
[0, 0],
[0, 0],
]
def paths_helper(x, y, path_grid, missing):
if path_grid[x][y] is not None:
return path_grid[x][y]
if missing[x][y]:
path_grid[x][y] = 0
return 0
elif x < 0 or y < 0:
return 0
else:
path_count = (paths_helper(x - 1, y, path_grid, missing) +
paths_helper(x, y - 1, path_grid, missing))
path_grid[x][y] = path_count
return path_count
def paths(missing):
arr = [[None] * w for _ in range(h)]
w = len(missing[0])
h = len(missing)
return paths_helper(w, h, arr, missing)
print paths()