输出描述
针对每一个矩阵,找出费用最小的路径,并将其输出。每个矩阵的输出包括两行,第一行是路径本身,即输出每一步所在的行,第二行则是该路径的费用。
如果对于同一个矩阵有多条不同的费用最小路径,则输出左端行号较小的一条。
输入样例
5 6
3 4 1 2 8 6
6 1 8 2 7 4
5 9 3 9 9 5
8 4 1 3 2 6
3 7 2 1 2 3
输出样例
1 2 1 5 4 5
11
*/
//思路: dp吧,需要注意的是它要返回路径,并且返回的是按行排列最小的,这是需要注意的。
#include <iostream> #include <cstring> using namespace std; long long a[10][102]; long long dp[10][102]; int n, m; long long fun(int i, int j){ //dp打表 if(dp[i][j]) return dp[i][j]; if(i >= n || i < 0) return 0; if(j == m - 1) return dp[i][j] = a[i][j]; if(i > 0 && i < n - 1){ dp[i][j] = min(fun(i + 1, j + 1), fun(i, j + 1)); return dp[i][j] = min(fun(i - 1, j + 1), dp[i][j]) + a[i][j]; } if(i == 0){ dp[i][j] = min(fun(i + 1, j + 1), fun(i, j + 1)); return dp[i][j] = min(fun(n - 1, j + 1), dp[i][j]) + a[i][j]; } if(i == n - 1){ dp[i][j] = min(fun(i - 1, j + 1), fun(i, j + 1)); return dp[i][j] = min(fun(0, j + 1), dp[i][j]) + a[i][j]; } } 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]; } long long min = fun(0, 0); int len = 0; for(int i = 1; i < n; i++){ //找到最短路的开始行 if(min > fun(i, 0)){ min = fun(i, 0); len = i; } // cout << fun(i, 0) << endl; } cout << len + 1; for(int i = len, j = 0; j < m - 1; j++){ // 通过已知行推出最短路 int mina = 0, mini = 0; // mina = dp[i][j - 1]; if(i > 0 && i < n - 1){ //由于数组的连续性是圆柱形,故分为四种情况考虑 mini = i - 1; //要优先选 i - 1; //保证是按最小行排列的 mina = dp[mini][j + 1]; if(dp[i - 1][j + 1] > dp[i][j + 1]){ mini = i; mina = dp[i][j + 1]; } if(mina > dp[i + 1][j + 1]){ mini = i + 1; i++; } else if(mini == i - 1){ i--; } cout << " " << mini + 1; continue; } if(i == 0){ mini = i; //保证是按最小行排列的 mina = dp[mini][j + 1]; if(dp[i][j + 1] > dp[i + 1][j + 1]){ mini = i + 1; mina = dp[i + 1][j + 1]; } if(mina > dp[n - 1][j + 1]){ mini = n - 1; i = n - 1; } else if(mini == i){ ; } else i++; cout << " " << mini + 1; continue; } if(i == n - 1){ mini = 0; //要优先选坐标小的,故 mini = 0; //保证是按最小行排列的 mina = dp[mini][j + 1]; if(dp[0][j + 1] > dp[i - 1][j + 1]){ mini = i - 1; mina = dp[i - 1][j + 1]; } if(mina > dp[i][j + 1]){ mini = i; } else if(mini == 0){ i = 0; } else i--; cout << " " << mini + 1; continue; } } cout << endl; cout << min; return 0; }