【发布时间】:2015-02-21 21:15:56
【问题描述】:
我得到了一个算法,可以帮助我解决以下问题:
采用NxN 网格。从左上角开始,仅从每个节点向下或向右遍历到右下角。例如:
grid = [[0,2,5],[1,1,3],[2,1,1]]
把这个列表想象成一个网格:
0 2 5
1 1 3
2 1 1
您访问的每个数字都必须添加到运行总数中。在这种情况下,有六种不同的方法可以为您提供总和。我得到的适用于此并返回可能总和列表的算法如下:
def gridsums(grid, x, y, memo):
if memo[x][y] is not None:
return memo[x][y]
if x == 0 and y == 0:
sums = [0]
elif x == 0:
sums = gridsums(grid, x, y-1, memo)
elif y == 0:
sums = gridsums(grid, x-1, y, memo)
else:
sums = gridsums(grid, x-1, y, memo) + gridsums(grid, x, y-1, memo)
sums = [grid[x][y] + s for s in sums]
memo[x][y] = sums
return sums
def gridsumsfast(grid):
memo = []
for row in grid:
memo.append([])
for cell in row:
memo[-1].append(None)
return gridsums(grid, len(grid[0]) - 1, len(grid) - 1, memo)
缩进不正确,但你明白了。然而,这适用于更大的 N 值,它根本不能很好地工作。例如,如果 N 值为 20,则需要很长时间,并且在某些测试中我运行它会超时。
显然,主要功能正在完成大量重复工作,那么我究竟如何使用该算法实现记忆化/动态编程?这项工作重复了很多次,让我有理由说需要实现动态编程,但是这条线:sum = [grid[x][y] = s for s in sums] 让我绊倒,因为x 和y 更改每个值,所以我只需要提交前一个总结成一个备忘录,但我不能完全理解这样做。
感谢任何正确方向的指导,谢谢。
【问题讨论】:
-
你想返回所有可能的总和(这很难,因为通常会有很多方法来进行遍历)?还是您只想知道最小的总和?
-
我需要全部,因为我需要根据给定的数字将全部与给定的数字进行比较。以前的算法非常有效,我正在尝试找到一种方法来使用 DP 让时间变得更好
-
所以您正在寻找(基本上)一种快速/好的方法来列出所有可能的遍历? (您可以从中确定成本)
-
是的!感谢您简化了我所说的内容,这正是我所需要的
-
列出所有可能遍历的总和...这样我们就清楚了
标签: python algorithm recursion dynamic-programming memoization