谁能告诉我为什么这两个代码给出不同的输出.它们不是具有两种不同实现的相同代码吗(一种是强力实现,另一种是使用动态编程).

程序描述:给出一个用非负数填充的m x n网格,找到一条从左上角到右下角的路径,它使路径上所有数字的和最小化.

def minPathSum_dp(grid):
        def dfs(i, j, pathSum):
            if (i, j) in dp:
                return dp[(i, j)]
            
            if i == len(grid)-1 and j == len(grid[i])-1:
                return pathSum + grid[i][j]

            if i == len(grid)-1:
                return dfs(i, j+1, pathSum + grid[i][j])
            
            if j == len(grid[i])-1:
                return dfs(i+1, j, pathSum + grid[i][j])
            
            path1 = dfs(i+1, j, pathSum + grid[i][j])
            path2 = dfs(i, j+1, pathSum + grid[i][j])
            dp[(i, j)] = min(path1, path2)
            return dp[(i, j)]
        
        dp = {}
        return dfs(0, 0, 0) 

def minPathSum_bf(grid):
        def dfs(i, j, pathSum):          
            if i == len(grid)-1 and j == len(grid[i])-1:
                return pathSum + grid[i][j]
            
            if i == len(grid)-1:
                return dfs(i, j+1, pathSum + grid[i][j])
            
            if j == len(grid[i])-1:
                return dfs(i+1, j, pathSum + grid[i][j])
            
            path1 = dfs(i+1, j, pathSum + grid[i][j])
            path2 = dfs(i, j+1, pathSum + grid[i][j])
            return min(path1, path2)
        
        return dfs(0, 0, 0) 

grid = [[1,4,8,6,2,2,1,7],[4,7,3,1,4,5,5,1],[8,8,2,1,1,8,0,1],[8,9,2,9,8,0,8,9],[5,7,5,7,1,8,5,5],[7,0,9,4,5,6,5,6],[4,9,9,7,9,1,9,0]]

UPDATED: WORKING SOLUTION

def minPathSum(self, grid: List[List[int]]) -> int:
        def dfs(i, j):
            if (i, j) in dp:
                return dp[(i, j)]
            
            if i == len(grid)-1 and j == len(grid[i])-1:
                return grid[i][j]
            
            if i == len(grid)-1:
                dp[(i, j)] = grid[i][j] + dfs(i, j+1)
                return dp[(i, j)]
            
            if j == len(grid[i])-1:
                dp[(i, j)] = grid[i][j] + dfs(i+1, j)
                return dp[(i, j)]
            
            path1 = grid[i][j] + dfs(i+1, j)
            path2 = grid[i][j] + dfs(i, j+1)
            dp[(i, j)] = min(path1, path2)
            return dp[(i, j)]
        
        dp = {}
        return dfs(0, 0)

print(minPathSum_dp(grid))
print(minPathSum_bf(grid))

推荐答案

(一个简短的术语说明-在我看来,您在这里所做的事情比动态编程更接近memoization,因为您是自上而下而不是自下而上地计算事情.)

您的递归函数有三个参数.前两个是"我现在在哪里?"第三个问题是"到目前为止,我在这条路上的总和是多少?"例如,如果您在(ROW,COL)处,呼叫dfs(row, col, 137)会给出您所能达到的最佳成本,而当前路径的成本是137,而如果您的当前路径成本是42,则呼叫dfs(row, col, 42)会给出成本.

然而,您的DP/Memoization表仅取决于前两个参数.这意味着您在位置(行,列)写下的值需要同时是dfs(row, col, 137)dfs(row, col, 42)的答案.但这显然行不通.

从技术上讲,你可以通过让你的DP/Memoization表写下所有三个参数的答案来解决这个问题.然而,这不会让事情快速运行,因为您不太可能以两个或更多的递归调用来结束对网格中相同位置的相同前缀sum的调用.

解决这个问题的更合适的方法是更改递归策略,这样到目前为止,您不需要路径成本的第三个参数.通过使用该参数,每个递归调用都必须知道实现该参数的特定调用链.相反,看看是否可以找到一种方法,使递归函数只接受一对(行,列),并返回从该点到目的地的最佳开销.一旦你得到了它的工作,你可以添加备忘录,它将工作得很好.

Python相关问答推荐

在Python中对分层父/子列表进行排序

比较两个数据帧并并排附加结果(获取性能警告)

非常奇怪:tzLocal.get_Localzone()基于python3别名的不同输出?

Pandas 都是(),但有一个门槛

根据二元组列表在pandas中创建新列

计算组中唯一值的数量

如何调整QscrollArea以正确显示内部正在变化的Qgridlayout?

Pandas DataFrame中行之间的差异

Scrapy和Great Expectations(great_expectations)—不合作

如何在FastAPI中为我上传的json文件提供索引ID?

判断solve_ivp中的事件

matplotlib图中的复杂箭头形状

当单元测试失败时,是否有一个惯例会抛出许多类似的错误消息?

GPT python SDK引入了大量开销/错误超时

如何在信号的FFT中获得正确的频率幅值

使用SQLAlchemy从多线程Python应用程序在postgr中插入多行的最佳方法是什么?'

用来自另一个数据框的列特定标量划分Polars数据框中的每一列,

将相应的值从第2列合并到第1列(Pandas )

如何在基于时间的数据帧中添加计算值

Sknowled线性回归()不需要迭代和学习率作为参数