给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
数据范围:
n <= 100,m <= 100;
输入:
3 3
1 3 1
1 5 1
4 2 1
输出:
7
这样走,路径上的数字总和为最小
解题思路:
我们首先定义dp[i][j]表示从左上角到(i,j)这个点的路径上的数字的最小总和,现在我们很容易想到关系表达式为:
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + a[i][j];
//表示从上一步路径数字最小总和+这个点的数字,结果为从左上角到这个点的路径最小数字和
然后我们思考如何初始化,如果i = 0,i-1就是-1,数组就会越界,也很容易想到怎么初始化:
dp[0][0] = a[0][0];for (int i = 1; i < n; i++) {dp[i][0] = dp[i - 1][0] + a[i][0];}for (int i = 1; i < m; i++) {dp[0][i] = dp[0][i - 1] + a[0][i];}
代码如下:
#include <iostream>
using namespace std;
const int N = 110;
int a[N][N];
int dp[N][N];int main() {int n, m;cin >> n >> m;for (int i = 0; i < n; i++)for (int j = 0; j < m; j++) {cin >> a[i][j];}dp[0][0] = a[0][0];for (int i = 1; i < n; i++) {dp[i][0] = dp[i - 1][0] + a[i][0];}for (int i = 1; i < m; i++) {dp[0][i] = dp[0][i - 1] + a[0][i];}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]) + a[i][j];}cout << dp[n - 1][m - 1] << endl;return 0;
}