路径类 DP 是线性 DP 的一种,通常在一个 n × m 的矩阵中设定行走规则,研究从起点到终点的方案数、最小路径和或最大路径和等问题。入门阶段的《数字三角形》其实也属于这一范畴。
矩阵的最小路径和
题目描述
思路解析
-
状态表示
dp[i][j]表示从[1, 1]格子走到[i, j]格子时,所有方案下的最小路径和。 -
状态转移方程 考虑最后一步,到达
(i, j)只能从上方(i-1, j)或左方(i, j-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];
}
}
// 初始化为无穷大
memset(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;
;
}


