题目
给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有路径中最小的路径和。
例子:
给定m如下:
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12。
使用动态规划,定义
dp[M][N]
, M ,N 分别代表矩阵的行和列数 dp[i][j] 表示从左上角到矩阵(i,j)位置是的最短路径和。则可知 到(i,j)位置有两种情况:1)由(i-1,j)向下走,2)由(i,j-1)向右走,所以dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+m[i][j];对于dp[0][j] 只能由 dp[0][j-1] 向右走,dp[i][0] 只能由 dp[i-1][0] 向下走。所以 dp[0][j]=dp[0][j-1]+m[0][j], dp[i][0]=dp[i-1][0]+m[i][0].
public static int shortestRoad(int arr[][])
int dp[][]=new int [arr.length][arr[0].length];
dp[0][0]=arr[0][0];
for(int i=1;i<arr.length;i++)
dp[i][0]=dp[i-1][0]+arr[i][0];
for(int j=1;j<arr[0].length;j++)
dp[0][j]=dp[0][j-1]+arr[0][j];
for(int i=1;i<arr.length;i++)
for(int j=1;j<arr[0].length;j++)
dp[i][j]=Math.min(dp[i-1][j], dp[i][j-1])+arr[i][j];
return dp[arr.length-1][arr[0].length-1];
解法2(优化解法1)
思路:
解法1中使用dp数组的空间大小为M*N,其实可以对dp数组的空间压缩至N,定义大小为N的dp数组,对于第一行,dp[i]=dp[i-1]+m[0][i],在求第二行中的 dp[i] 时可以覆盖第一行 dp[i] ,第二行dp[i]=Math.min(dp[i],dp[i-1])+m[i][j]。
public static int shortestRoad1(int arr[][])
int dp[]=new int[arr[0].length];
dp[0]=arr[0][0];
for(int j=1;j<arr[0].length;j++)
dp[j]=dp[j-1]+arr[0][j];
for(int i=1;i<arr.length;i++)
dp[0]=arr[i][0]+dp[0];
for(int j=1;j<arr[0].length;j++)
dp[j]=Math.min(dp[j-1]+arr[i][j], dp[j]+arr[i][j]);
return dp[arr[0].length-1];
给定一个M×N的矩阵,定义一条路径为:从矩阵左上顶点数字出发到达右下数字,每一次只可以从一个数字出发向右移动一步或向下移动一步,定义路径和为:路径经过的数字的和。要求编写一个程序,找到路径和最小的那条路径,并给出最小路径和。
给定如图所示矩阵:一条路径为2->0->3->6->9->5,路径和为25
[2 ,0 ,11,1 ]
[4 ,3 ,6 ...
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图中的最短路径。小蓝的图由2021 个结点组成,依次编号1 至2021。对于两个不同的结点a, b,如果a 和b 的差的绝对值大于21,则两个结点之间没有边相连;如果a 和b的差的绝对值小于等于21,则两个点之间有一条长度为a 和b 的最小公倍数的无向边相连。例如:结点1 和结点23 之间没有边相连;结点3和结点24 之间有一条无向边,长度为24;结点15 和结点25 之间有一条无向边,长度为75。请计算,结点1 和结点2021。
一、牛客 NC59 矩阵的最小路径和
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
数据范围: 1≤n,m≤500,矩阵中任意值都满足 0 ≤ a(i,j) ≤100
要求:时间复杂度 O(nm)O(nm)
例如:当输入[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]时,对应的返回值为12,
所选择的最小累加和路径如下图所示:
public int min
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。两个相邻元素间的距离为 1。
将找每个元素距离最近的0转换为从0向外找1,因为如果该位置元素为0,那么他到0的距离就是0,所以找到1的距离就是1到0的距离。用广度优先算法来寻找最短距离。
//广度优先算法 ---从0向四周搜索1,就是最短路径
public int[][] updateMatri...
private int[][] grid = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
int m = grid.length;
int n = grid[0].length;
int sum = 0;
if (m < 1 || n &
其实用dp[][]二维矩阵处理这题更好理解,但为了减少空间所以用了一维的dp,但还是二维的思路阐述。
1、确定dp数组以及下标的含义——这里dp[i][j]表示到达(i,j)点的最小路径和
2、确定递推公式,(i,j)点只能由上方点和左方点到达,所以dp[i][j]...
二维矩阵从左上角到右下角路径的最小和(JAVA代码)—动态规划
给定一个二维数组m行,n列。假设这个二维数组中每个单元格的值都是正整数,表示从该单元格经过时需要花费的成本。
那么求从右上角第一个单元格到右下角最后一个单元格的路径中,花费的最小成本是多少?
约束条件为:你只能向右,向下,或者向右下(对角线方向)走。
给定一个m=3,n=3的二维数组cost,如下图所示,从左上角的第...
给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
m n 4 4
1 3 5 9
8 1 3 4
5 0 6 1
8 8 4 0
输出:12
更新整个矩阵
第一行和第一列只需要直接求和更新即可
其余部分可以看到 矩阵只能从左边或者上边经过,只需要比较左边和上边的数的大小,取小的即可。
public int MinPathSum1(int[][] m){
if (m ==
解释:因为路径 1→3→1→1→1 的总和最小。
提示: m == grid.length n == grid[i].length 1 <= m, n <= 200 0 <=grid[i][j] <= 100
步骤一、定义数组元素的
* 问题给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到右下角的位置,路径上所有的数字累加起来就是路径和,返回所有的路径中最小的路径和。1 -> 3 5 98 1 3 45 0 -> 6 -> 18 8 4 0打印最小路径:1->3->1->0->6->1->0packag...
介绍这里讲的顶点对之间的最短路径是基于动态规划在图中的实现。每一个循环都类似矩阵乘法,因此这个算法看起来就像是一直在做矩阵乘法。实现在这里我们用邻接矩阵表示法来表示一个图,因为相对邻接表来说,邻接矩阵表示要容易些,并且采用自底而下的算法来计算最短路径权重。typedef int (*Metrix)[VERTEX_NUMBER];
void printfMatrix(Metrix ...
[DP题解]矩阵最小路径和问题
【题目】给定一个矩阵,例如demo,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有的路径和中最小的路径和。
算法分析:
这是一个典型的动态规划算法问题。
分析如下:
例如下图中的矩阵demo,1-3-1-0-6-1-0 的路径和最小,值为12.
由此进行算法设计:
给定带权有向图 G=(V, E), 对任意顶点vi,vj 属于V,(i!=j) 求顶点vi到顶点vj的最短路径
解决办法: 弗洛伊德提出的求每一对顶点之间的最短路径算法-----Floyd算法
基本思想:对于