【发布时间】:2017-08-13 21:08:38
【问题描述】:
我正在解决关于 LeetCode 的一些问题。其中一个问题是:
给定一个由非负数填充的 m x n 网格,找到一条从左上角到右下角的路径,该路径使沿其路径的所有数字的总和最小化。您只能在任何时间点向下或向右移动。
社论和发布的解决方案都使用动态编程。最受欢迎的解决方案之一如下:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int> > sum(m, vector<int>(n, grid[0][0]));
for (int i = 1; i < m; i++)
sum[i][0] = sum[i - 1][0] + grid[i][0];
for (int j = 1; j < n; j++)
sum[0][j] = sum[0][j - 1] + grid[0][j];
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
sum[i][j] = min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j];
return sum[m - 1][n - 1];
}
};
我的问题很简单:不应该使用回溯来解决这个问题吗?假设输入矩阵是这样的:
[
[1,2,500]
[100,500,500]
[1,3,4]
]
我的怀疑是因为在 DP 中,子问题的解决方案是全局解决方案(最优子结构)的一部分。但是,如上所示,当我们从(2,100) 中选择2 时,我们可能是错误的,因为未来的路径可能过于昂贵(2 周围的所有数字都是500s)。那么,在这种情况下如何使用动态规划呢?
总结一下:
- 我们是否应该使用回溯,因为如果我们之前做出了错误的选择(查看局部最大值),我们可能不得不撤回我们的路径?
- 这是一个动态规划问题吗?
P.S.:上面的解决方案肯定可以运行。
【问题讨论】:
-
你什么时候回溯?您评估了多少条路径/单元格?
-
@Jarod42,我不知道。但我想我应该。这正是我的问题!
标签: c++ algorithm dynamic-programming