路径类 DP 是线性 DP 的一种变体,主要研究在 n × m 矩阵中,根据特定行走规则,计算从起点到终点的方案数、最小路径和等问题。入门阶段的《数字三角形》其实也是这类问题的雏形。
矩阵的最小路径和
题目描述
思路解析
-
状态表示
dp[i][j]表示从[1, 1]格子走到[i, j]格子时,所有方案下的最小路径和。 -
状态转移方程 我们通常从最后一步来推导。要到达
(n, m),只能从上方(n-1, m)或左方(n, m-1)过来。因此取两者的较小值加上当前格子的权值:dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + a[i][j] -
初始化 填表时需要访问左边和上边的格子,所以第一行和第一列的边界比较特殊。为了避免数组越界并简化逻辑,我们将第 0 行和第 0 列初始化为无穷大。这样在取最小值时,永远不会选中这些无效位置。 同时,将
dp[1][1]初始化为a[1][1],因为起点的代价就是它本身。注意填表循环时要跳过起点,否则会被错误覆盖。 -
填表顺序 从上往下,从左往右。
-
输出结果
dp[n][m]
#include <iostream>
#include <cstring>
using namespace std;
const int N = 510;
int n, m;
int a[N][N], dp[N][N];
int main() {
// 处理输入
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
// 初始化:第 0 行和第 0 列设为无穷大
(dp, , (dp));
dp[][] = a[][];
( i = ; i <= n; i++) {
( j = ; j <= m; j++) {
(i == && j == ) ;
dp[i][j] = (dp[i - ][j], dp[i][j - ]) + a[i][j];
}
}
cout << dp[n][m] << endl;
;
}


