矩阵的最小路径和

本文介绍如何使用动态规划算法求解二维矩阵中从左上角到右下角的最小路径和,通过计算每个单元格的最短路径并更新dp数组实现。

 

import java.util.*;


public class Solution {
    public int minPathSum(int[][] matrix) {
        int row = matrix.length;
        int cow = matrix[0].length;
        int[][] dp = new int[row + 1][cow + 1];
        for (int i = 1; i <= row ; i++) {
            for (int j = 1; j <= cow; j++) {
                if (i == 1) {
                    dp[i][j] = dp[i][j - 1] + matrix[i - 1][j - 1];
                } else if (j == 1) {
                    dp[i][j] = dp[i - 1][j] + matrix[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i][j - 1], dp[i - 1][j]) + matrix[i - 1][j - 1];
                }
            }
        }
        return dp[row][cow];
    }
}

在XDOJ平台上解决矩阵最小路径的问题,通常是指在一个二维矩阵中从左上角到右下角找到一条路径,使得路径上所有元素的最小。该问题可以通过动态规划(Dynamic Programming)的方法高效求解。 ### 问题描述 假设给定一个 $ n \times m $ 的矩阵,其中每个位置 $(i, j)$ 上的值表示通过该位置所需付出的代价。目标是从起点 $(0, 0)$ 移动到终点 $(n-1, m-1)$,每次只能向右或向下移动一步,要求找出所有可能路径中总代价最小的一条路径。 ### 动态规划解决方案 使用动态规划的思想来解决此问题。定义一个新的二维数组 `dp`,其中 `dp[i][j]` 表示从起点到达位置 $(i, j)$ 的最小路径。状态转移方程如下: - **初始条件**: - `dp[0][0] = matrix[0][0]`:起点的最小路径就是其自身的值。 - **状态转移方程**: - 如果是第一行(即 $ i=0 $ 且 $ j>0 $),则只能从左边转移过来: ```cpp dp[i][j] = dp[i][j-1] + matrix[i][j]; ``` - 如果是第一列(即 $ j=0 $ 且 $ i>0 $),则只能从上方转移过来: ```cpp dp[i][j] = dp[i-1][j] + matrix[i][j]; ``` - 如果是中间位置(即 $ i>0 $ 且 $ j>0 $),则可以从上方或左边选择较小的那个转移过来: ```cpp dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + matrix[i][j]; ``` 最终的答案就是 `dp[n-1][m-1]`,即终点位置的最小路径。 ### 示例代码实现 以下是一个完整的 C++ 实现示例: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int minPathSum(vector<vector<int>>& matrix) { int n = matrix.size(); int m = matrix[0].size(); // 创建 dp 数组 vector<vector<int>> dp(n, vector<int>(m, 0)); // 初始化第一个元素 dp[0][0] = matrix[0][0]; // 填充第一行 for (int j = 1; j < m; ++j) { dp[0][j] = dp[0][j - 1] + matrix[0][j]; } // 填充第一列 for (int i = 1; i < n; ++i) { dp[i][0] = dp[i - 1][0] + matrix[i][0]; } // 填充剩余部分 for (int i = 1; i < n; ++i) { for (int j = 1; j < m; ++j) { dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + matrix[i][j]; } } return dp[n - 1][m - 1]; } int main() { int n, m; cin >> n >> m; vector<vector<int>> matrix(n, vector<int>(m)); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> matrix[i][j]; } } cout << "最小路径为: " << minPathSum(matrix) << endl; return 0; } ``` ### 空间优化方案 如果希望进一步优化空间复杂度,可以将 `dp` 数组与原始矩阵合并使用原地更新,或者仅使用一维数组进行优化。例如,使用一维数组 `dp` 来存储当前行的最小路径,逐步更新每一行的结果。 ### 时间与空间复杂度分析 - **时间复杂度**:$ O(n \times m) $,需要遍历整个矩阵一次。 - **空间复杂度**:如果不进行优化,为 $ O(n \times m) $;若使用一维数组优化,则可降低至 $ O(m) $ 或 $ O(n) $。 ### 总结 通过动态规划方法,可以在多项式时间内高效求解矩阵中的最小路径问题。该方法不仅适用于标准的 $ n \times m $ 矩阵,还可以扩展到其他类似的路径规划问题,如最大路径、带障碍物的路径等场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值