题目:
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
leetcode原题链接
思路:
DFS
- 由于直接暴力DFS会超时,这里采用一个嵌套列表record来记录已计算过的dfs(i,j)的值。
嵌套列表record初始化,元素全为0,因为m*n的棋盘中每个礼物都有价值(每个元素都大于0),计算过dfs(i,j)后,record[i][j]必然大于0,以此来判断,当前i和j的dfs函数是否计算过。从而避免重复计算。
优化DFS思路参考 - 需要特别注意,嵌套列表record的创建,若采用record=[[0]*n]*m,得到的错误嵌套列表会影响函数最终返回值。
代码:
class Solution:
def maxValue(self, grid: List[List[int]]) -> int:
def dfs(i,j):
if i==m or j==n: return 0
if record[i][j]>0: return record[i][j]
right=grid[i][j]+dfs(i, j+1)
down=grid[i][j]+dfs(i+1, j)
record[i][j]=max(right,down)
return record[i][j]
m=len(grid)
n=len(grid[0])
record=[[0]*n for _ in range(m)]
return dfs(0,0)
DFS 原超时代码:
class Solution:
def maxValue(self, grid: List[List[int]]) -> int:
def dfs(m,n,i,j):
if i==m or j==n: return 0
right=grid[i][j]+dfs(m,n, i, j+1)
down=grid[i][j]+dfs(m,n, i+1, j)
return max(right,down)
m=len(grid)
n=len(grid[0])
return dfs(m,n,0,0)