【发布时间】:2021-12-05 03:15:12
【问题描述】:
我正在编写一个程序来遍历从左下角到右上角的网格,其中有效的移动是向右移动 1,向上移动 1,或者向上或向右跳跃指定的数量跳转数组。输入是二维数组格式的网格、网格的维度:X 和 Y,以及必须按顺序完成跳跃的跳跃数组。输出是最短路径,其中路径的长度是所有触摸的数字的总和,包括左下角和右上角。
示例输入:
Grid:
[9 9 1]
[9 9 1]
[3 9 1]
Jumps: [1 1] X:3, Y:3
输出将是 5,因为我们从 (0,0) 开始,即 3,然后使用第一个 1 块跳转到 (2, 0),即 1,然后第二个块跳转到 (2, 2) 是 1,所以 3+1+1 = 5。如果 jumps 数组只有 [1],那么输出将是 6,因为我们必须从 (2,0) 移动到 (2,1) 到 (2 ,2)。
这是我的第一个解决方案,它似乎适用于较小的输入,但只能在较大的输入上永远运行:
def get(grid, x, y, endX, endY):
if (x > endX or y > endY):
return False
return grid[y][x]
def fly(x, y, grid, jumps, endX, endY):
if x > endX or y > endY:
return float('inf')
if (x == endX and y == endY):
return get(grid, endX, endY, endX, endY)
flyup = fly(x, y+1, grid, jumps, endX, endY)
flyright = fly(x+1, y, grid, jumps, endX, endY)
if (len(jumps) > 0):
jumpup = fly(x, y+jumps[0]+1, grid, jumps[1:], endX, endY)
jumpright = fly(x+jumps[0]+1, y, grid, jumps[1:], endX, endY)
temp = min(flyup, flyright, jumpup, jumpright)
return get(grid, x, y, endX, endY) + temp
else:
temp = min(flyup, flyright)
return get(grid, x, y, endX, endY) + temp
fly(0, 0, grid, jumps, X-1, Y-1)
这是我使用 DP 编写的另一个解决方案(或者我对 DP 的理解,因为我刚学会它),但这个似乎只适用于某些输入,我无法识别模式。
def fly2(x, y, grid, jumps):
dp = [[0 for i in range(len(grid[0]))] for j in range(len(grid))]
for row in range(len(grid)):
for col in range(len(grid[0])):
if row == 0 and col == 0:
dp[row][col] += get2(grid, col, row)
else:
flyup = float('inf') if row==0 else dp[row-1][col]
flyright = float('inf') if col==0 else dp[row][col-1]
jumpup = float('inf') if row < jumps[0]+1 else dp[row-jumps[0]-1][col]
jumpright = float('inf') if col < jumps[0]+1 else dp[row][col-jumps[0]-1]
shortest = min(flyup, flyright, jumpup, jumpright)
if min == jumpup or min == jumpright:
jumps = jumps[1:]
dp[row][col] += get2(grid, col, row) + shortest
return dp[len(grid)-1][len(grid[0])-1]
我需要一些帮助来加快第一个或找出第二个有什么问题,或者获得一些关于如何有效编写此代码的其他想法。谢谢
【问题讨论】:
-
DP表需要另外一个维度,就是使用的跳转次数。
标签: python algorithm dynamic-programming