最小路径和

GitHub跳转原题关系图返回列表

网格 DP:边界只能来自单方向,内部取上左较小值加上当前格。

OJ: leetcodecn

题目 ID: minimum-path-sum

难度:普及-

标签:动态规划网格

日期: 2026-07-29 12:55

题意

网格从左上到右下,只能向右或向下,求最小路径和。

思路

dp[j] 表示到达当前行第 j 列的最小路径和。首行只累加,内部 dp[j] = min(dp[j], dp[j-1]) + grid[i][j](上方和左方取较小值)。

代码

cpp
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
    int minPathSum(vector<vector<int>> &grid) {
        int m = grid.size(), n = grid[0].size();
        vector<int> dp = grid[0];
        for (int j = 1; j < n; j++)
            dp[j] += dp[j - 1];
        for (int i = 1; i < m; i++) {
            dp[0] += grid[i][0];
            for (int j = 1; j < n; j++)
                dp[j] = grid[i][j] + min(dp[j], dp[j - 1]);
        }
        return dp[n - 1];
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int m, n;
    cin >> m >> n;
    vector<vector<int>> g(m, vector<int>(n));
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            cin >> g[i][j];
    cout << Solution().minPathSum(g) << '\n';
    return 0;
}
python
#!/usr/bin/env python3
from typing import List


class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        dp = grid[0][:]
        for j in range(1, n):
            dp[j] += dp[j - 1]
        for i in range(1, m):
            dp[0] += grid[i][0]
            for j in range(1, n):
                dp[j] = grid[i][j] + min(dp[j], dp[j - 1])
        return dp[-1]


def main():
    m, n = map(int, input().split())
    g = [list(map(int, input().split())) for _ in range(m)]
    print(Solution().minPathSum(g))


if __name__ == "__main__":
    main()

复杂度

  • 时间复杂度:O(mn)O(mn)
  • 空间复杂度:O(n)O(n)

总结

最小路径和与不同路径的转移结构相同,只是把"加法计数"换成"取最小值加权重"。