动态规划最小路径和之路径坐标正确输出

在学习动态规划算法时,遇到了一个算法编程题如下:

寻找一条从左上角 (arr[0][0])到右下角(arr[m-1][n-1])的路线,使得沿途经过的数组中的整数和最小。

给的程序中有输出路径坐标的代码,可输出的坐标和实际的路径坐标差别很大。 题目给的参考代码如下:

public class ShortestPath {
	public static int getMinPath(int[][] arr) {
		if(arr==null||arr.length==0) {
			return 0;
		}
		int row = arr.length;
		int col = arr[0].length;
		//用来保存计算的中间值
		int[][] cache = new int[row][col];
		cache[0][0] = arr[0][0];
		for(int i = 1;i < col;i++) {
			cache[0][i] = cache[0][i-1]+arr[0][i];
		}
		for(int j = 1;j < row;j++) {
			cache[j][0] = cache[j-1][0]+arr[j][0];
		}
		//在遍历二维数组的过程中不断把计算结果保存到cache中
		for(int i = 1; i < row; i++) {
			for(int j = 1; j < col; j++) {
				//可以确定选择路线为arr[i][j-1]
				if(cache[i-1][j] > cache[i][j-1]) {
					cache[i][j] = cache[i][j-1] + arr[i][j];
					System.out.print("["+i+","+(j-1)+"]");
				}
				else {
					cache[i][j] = cache[i-1][j] + arr[i][j];
					System.out.print("["+(i-1)+","+j+"]");
				}
			}
		}
		System.out.println("["+(row-1)+","+(col-1)+"]");	
		return cache[row - 1][col - 1];
	}
	public static void main(String[] args) {	
		int[][] arr = {{1,4,3},{8,7,5},{2,1,5}};
		System.out.print("路径:");
		System.out.print("最小值为:"+getMinPath(arr));
	}
}

输出结果:

路径:[0,1][0,2][2,0][2,1][2,2]
最小值为:17

红圈代表路径坐标
路径坐标显然不对,自己便对上面的参考程序进行了一点修改,使得路径坐标能按照从终点到起点的顺序输出。

修改是根据自顶向下的思想,从终点开始比较两个值(左边的值和上边的值)的大小,从而一路确定路径坐标,由于值的大小已存入cache二维数组中(备忘录方法),避免了重复求解。特别注意:当 i 或 j减为0时,就不能继续减了,所以这里要进行判断。

修改的程序如下:

public class ShortestPathPlus {
	public static int getMinPath(int[][] arr) {
		if(arr==null||arr.length==0) {
			return 0;
		}
		int row = arr.length;
		int col = arr[0].length;
		//用来保存计算的中间值
		int[][] cache = new int[row][col];
		cache[0][0] = arr[0][0];
		for(int i = 1;i < col;i++) {
			cache[0][i] = cache[0][i-1]+arr[0][i];
		}
		for(int j = 1;j < row;j++) {
			cache[j][0] = cache[j-1][0]+arr[j][0];
		}
		//在遍历二维数组的过程中不断把计算结果保存到cache中
		for(int i = 1; i < row; i++) {
			for(int j = 1; j < col; j++) {
				//可以确定选择路线为arr[i][j-1]
				if(cache[i-1][j] > cache[i][j-1]) {
					cache[i][j] = cache[i][j-1] + arr[i][j];
				}
				else {
					cache[i][j] = cache[i-1][j] + arr[i][j];
				}
			}
		}
		//最短路径坐标从终点到起点输出
		System.out.print("["+(row-1)+","+(col-1)+"]");
		for(int i = row-1,j = col-1; i > 0||j > 0;) {
			{
				if(cache[i-1][j] > cache[i][j-1]) {
					System.out.print("["+i+","+(j-1)+"]");
					j = j-1;
				}
				else {
					System.out.print("["+(i-1)+","+j+"]");
					i = i-1;
				}
			}			
			if(i == 0) {
				for(j = j - 1; j > 0; j--) {
					System.out.print("["+i+","+j+"]");
				}
				break;
			}
			if(j == 0) {
				for(i = i - 1; i > 0; i--) {
					System.out.print("["+i+","+j+"]");
				}
				break;
			}
			
		}
		System.out.println("["+0+","+0+"]");
		return cache[row - 1][col - 1];
	}
	public static void main(String[] args) {
		int[][] arr = {{1,4,3},{8,7,5},{2,1,5}};
//		int[][] arr = {{1,8,2},{4,7,1},{3,5,5}};
		System.out.print("路径:");
		System.out.print("最小值为:"+getMinPath(arr));
	}
}

输出结果:

路径:[2,2][2,1][2,0][1,0][0,0]
最小值为:17

红圈表示路径坐标
显然修改了的程序可以输出正确的路径坐标。

本人水平有限,有错误请大家批评指正!

感谢大家的阅读!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值