转自:https://blog.csdn.net/qq_27703417/article/details/70981769
题目:有一个矩阵map,它每个格子有一个权值。从左上角的格子开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有的路径中最小的路径和。
给定一个矩阵map及它的行数n和列数m,请返回最小路径和。保证行列数均小于等于100.
测试样例:[[1,2,3],[1,1,1]],2,3返回:4
思路:单纯从问题来看,这是一个非常复杂的问题,需要大量的遍历操作。分析得知:每一个位置map[i][j]只可能来自map[i][j-1]向右走一个结点或者map[i-1][j]向下走一个结点,因此只需要比较到达map[i][j-1]和到达map[i-1][j]的路径较小值加上map[i][j]就是所求答案,这时考虑使用递归,但是可知,这种递归处理属于暴力搜索的方式,因为没有对任何已经计算出来的结果进行保存和复用,因此上面这种思路是低效或者不符合要求的,应该使用动态规划来解决问题。
动态规划思想:先求简单值在逐步递推求复杂值,后面的值通过前面的结果来求得。
思路:求出到达每一个结点map[i][j]的最小路径将其保存在数组dp[i][j]中,求任意dp[i][j]的值完全依赖于dp[i-1][j]和dp[i][j-1],因此先求出dp[][]数组的第1行和第1列,然后从上到下,从左到右计算出每一个位置的结果值。
①创建一个二维数组记录每个位置的最小路径dp[n][m];
②求出dp[][]中第1行和第1列的结果填充到dp[][]中;注意:在动态规划问题中第1行和第1列需要手动求出,需要根据问题的要求进行求解,一般第1行和第1列的求解很简单。
③从上到下,从左到右,通过二重循环求出任意dp[i][j]的结果填充到dp[][]中;注意:二重循环中i,j都是从1开始进行遍历,即从矩阵第2行第2列的位置开始填充。
④最后dp[n-1][m-1]就是所求的结果。
-
import java.util.*;
-
//矩阵最短路径和问题:动态规划4部曲
-
public
class MinimumPath {
-
public int getMin(int[][] map, int n, int m) {
-
//特殊输入
-
if(map==
null||n<=
0||m<=
0)
return
0;
-
//①创建动态规划结果矩阵dp[][]
-
int[][] dp=
new
int[n][m];
-
//②求解第1行第1列的结果值
-
dp[
0][
0]=map[
0][
0];
-
for(
int i=
1;i<m;i++){
-
dp[
0][i]=dp[
0][i-
1]+map[
0][i];
-
}
-
//求第1列的结果值
-
for(
int i=
1;i<n;i++){
-
dp[i][
0]=dp[i-
1][
0]+map[i][
0];
-
}
-
//③从上到下,从左到右求任意dp[i][j]
-
for(
int i=
1;i<n;i++){
-
for(
int j=
1;j<m;j++){
-
dp[i][j]=map[i][j]+Math.min(dp[i-
1][j],dp[i][j-
1]);
-
}
-
}
-
//④返回右下角的结果值
-
return dp[n-
1][m-
1];
-
}
-
}