给定一个m行n列的矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,路径上的所有数字累加起来作为这条路径的路径和。求所有路径和中最小路径和。
函数接口定义:
void minpath();//求最小和路径ans void Disppath();//输出最小和路径
裁判测试程序样例:
#include <stdio.h> #include <vector> #include <stack> #include <string.h> #include <iostream> using namespace std; #define MAXN 100 int a[MAXN][MAXN]; int n,m; int ans=0; int dp[MAXN][MAXN]; int pre[MAXN][MAXN]; void minpath();//求最小和路径ans void Disppath();//输出最小和路径 int main() { memset(pre,0,sizeof(pre)); memset(dp,0,sizeof(dp)); scanf("%d%d",&m,&n); for (int i=0;i<m;i++) for (int j=0;j<n;j++) scanf("%d",&a[i][j]); minpath(); Disppath(); printf("\n%d",ans); return 0; } /* 请在这里填写答案 */
输入格式:
首先输入行数m及列数n,接下来输入m行,每行n个数。
输出格式:
输出第一行为最小路径(假定测试数据中的最小路径唯一),第2行为最小路径和。
输入样例1:
4 4
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
输出样例1:
1 3 1 0 6 1 0
12
题解:
void minpath() {
dp[0][0] = a[0][0];
// 初始化第一列的最小路径和
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i-1][0] + a[i][0];
pre[i][0] = 0;
}
// 初始化第一行的最小路径和
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j-1] + a[0][j];
pre[0][j] = 1;
}
// 动态规划求解最小路径和
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (dp[i-1][j] < dp[i][j-1]) {
dp[i][j] = dp[i-1][j] + a[i][j];
pre[i][j] = 0;
} else {
dp[i][j] = dp[i][j-1] + a[i][j];
pre[i][j] = 1;
}
}
}
ans = dp[m-1][n-1];
}
void Disppath() {
stack<int> path;
int i = m - 1;
int j = n - 1;
while (i > 0 || j > 0) {
path.push(a[i][j]);
if (pre[i][j] == 0)
i--;
else
j--;
}
path.push(a[0][0]);
while (!path.empty()) {
cout << path.top() << " ";
path.pop();
}
}
运行结果: