1、问题:只允许向下或者向右,求从左上到右下的最短距离,动态规划法

1 6 3 1 1 1
6 0 2 5 1 1
3 2 0 3 4 1
1 5 3 0 2 3
6 7 4 7 5 2
2 6 1 3 4 9
 1 public int minPathSum(int[][] grid) {
 2     if(grid==null || grid.length==0) return 0;
 3     int m = grid.length;
 4     int n = grid[0].length;
 5     int[][] p = new int[m][n];
 6     for (int i = 0; i < m; i++) {
 7         for (int j = 0; j < n; j++) {
 8             if (i == 0 && j == 0)
 9                 p[i][j] = grid[i][j];
10             else if (i == 0 && j > 0)
11                 p[i][j] = p[i][j-1] + grid[i][j];
12             else if (i > 0 && j == 0)
13                 p[i][j] = p[i-1][j] + grid[i][j];
14             else
15                 p[i][j] = Math.min(p[i-1][j], p[i][j-1]) + grid[i][j];
16         }
17     }
18     return p[m-1][n-1];
19 }

2、问题:允许上下左右走,求从左上到右下的最短距离

1 6 3 1 1 1
6 0 2 5 1 1
3 2 0 3 4 1
1 5 3 0 2 3
6 7 4 7 5 2
2 6 1 3 4 9

每个方格看成是一个点,可以构造N*M+2(源点和目标点)个点的图,然后用最短路径算法求解

法1:下面是dijkstra算法

 1 public void dijkstra(int[][] graph, int source){
 2     int n = graph.length;
 3     int[] dis = new int[n];
 4     boolean[] set = new boolean[n];
 5     // 初始化
 6     for(int i=0; i<n; i++){
 7         // -1表示不可达
 8         dis[i] = graph[source][i];
 9     }
10     dis[source] = 0;
11     set[source] = true;
12
13     for(int i=0; i<n-1; i++){
14         // 找到V中距离源点最近的点
15         int mindis = Integer.MAX_VALUE;
16         int minIndex=0;
17         for(int v=0; v<n; v++){
18             if(!set[v] && dis[v]<mindis && dis[v]!=-1){
19                 mindis = dis[v];
20                 minIndex = v;
21             }
22         }
23
24         // 更新源点到V中每个点的距离
25         set[minIndex] = true;
26         for(int v=0; v<n; v++){
27             if(!set[v] && graph[minIndex][v]>0 && dis[v] > dis[minIndex]+graph[minIndex][v]){
28                 dis[v] = dis[minIndex]+graph[minIndex][v];
29             }
30         }
31     }
32 }

法2:用优先队列方法,广度优先搜索

优先队列存点v和源点到v的最短路径。

代码

  1 package hihocoder;
  2
  3 import java.util.*;
  4
  5 public class WaterCity2{
  6
  7     private PriorityQueue<Point> queue = new PriorityQueue<>();
  8     private Set<Integer> visited = new HashSet<>();
  9     private int n, m;
 10     private int[] distN, distM;
 11     private Point[][] street;
 12
 13     private class Point implements Comparable<Point>{
 14         int r;
 15         int c;
 16         int dis;
 17         boolean blocked = false;
 18         boolean visited = false;
 19
 20         private Point(int r, int c) {
 21             this.r = r;
 22             this.c = c;
 23         }
 24
 25         private void visitNeighbors(){
 26             if(r!=0)    update(street[r-1][c], distN[r-1]);
 27             if(r!=n-1)  update(street[r+1][c], distN[r]);
 28             if(c!=0)    update(street[r][c-1], distM[c-1]);
 29             if(c!=m-1)  update(street[r][c+1], distM[c]);
 30         }
 31
 32         private void update(Point p, int len){
 33             if(!p.blocked && !p.visited && p.dis > dis + len){
 34                 queue.remove(p);
 35                 p.dis = dis + len;
 36                 queue.add(p);
 37             }
 38         }
 39
 40         @Override
 41         public int compareTo(Point p){
 42             return dis-p.dis;
 43         }
 44     }
 45
 46     private int minPath(int r0, int c0, int r1, int c1){
 47         Point start = street[r0][c0];
 48         Point end = street[r1][c1];
 49         queue.clear();
 50         visited.clear();
 51         for (int i = 0; i < n; i++) {
 52             for (int j = 0; j < m; j++) {
 53                 street[i][j].visited = false;
 54                 street[i][j].dis = Integer.MAX_VALUE;
 55             }
 56         }
 57
 58         start.dis = 0;
 59         queue.add(start);
 60         while(!queue.isEmpty()){
 61             Point cur = queue.poll();
 62             if(cur == end) return cur.dis;
 63             cur.visited = true;
 64             cur.visitNeighbors();
 65         }
 66         return -1;
 67     }
 68
 69     public void deal() {
 70         try(Scanner scanner = new Scanner(System.in)) {
 71             while (scanner.hasNextInt()) {
 72                 n = scanner.nextInt();
 73                 m = scanner.nextInt();
 74                 distN = new int[n-1];
 75                 distM = new int[m-1];
 76                 for (int i = 0; i < n - 1; i++) {
 77                     distN[i] = scanner.nextInt();
 78                 }
 79                 for (int i = 0; i < m - 1; i++) {
 80                     distM[i] = scanner.nextInt();
 81                 }
 82
 83                 street = new Point[n][m];
 84                 for (int i = 0; i < n; i++) {
 85                     for (int j = 0; j < m; j++) {
 86                         street[i][j] = new Point(i, j);
 87                     }
 88                 }
 89
 90                 int k = scanner.nextInt();
 91                 for (int i = 0; i < k; i++) {
 92                     street[scanner.nextInt()-1][scanner.nextInt() - 1].blocked = true;
 93                 }
 94
 95                 int q = scanner.nextInt();
 96                 for (int i = 0; i < q; i++) {
 97                     System.out.println(minPath(scanner.nextInt()-1, scanner.nextInt()-1,
 98                             scanner.nextInt()-1, scanner.nextInt()-1));
 99                 }
100             }
101         }
102     }
103
104     public static void main(String[] args){
105         new WaterCity2().deal();
106     }
107 }

转载于:https://www.cnblogs.com/shizhh/p/5728558.html

矩阵从左上到右下的最短距离问题相关推荐

  1. 记录java从左上到右下打印二维数组,从左下到右上打印二维数组

    左上到右下 public static void main(String[] args) {int[][] matrix = new int[][]{new int[]{2, 3, 5,10},new ...

  2. ppstructure分析的结果,保存切片图片时,如何矫正图片?好像bbox只有左上和右下2个坐标,缺少右上和坐下2个坐标,没法矫正?不矫正,导致部分文字不全。weixin: nlanguage

    ppstructure分析的结果,保存切片图片时,如何矫正图片?好像bbox只有左上和右下2个坐标,缺少右上和坐下2个坐标,没法矫正?不矫正,导致部分文字不全. 原图 ppstructure切割后图片

  3. 058:vue+openlayers用moveend事件获取地图左上和右下的坐标信息(示例代码)

    第058个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers中使用extent,利用moveend事件获取地图左上和右下的坐标信息. 直接复制下面的 vue+openlayers ...

  4. 动态规划 -- 二维数组中左上到右下的最短路径和。

    目录 问题: 应用场景: 分析: C++实现 问题: 给定一个二维数组map[4][4] ={{1,3,5,9},{8,1,3,4},{5,0,6,1},{8,8,4,0}}.求从左上角到右下角的最短 ...

  5. 给盒子左上和右下加边框角

    给盒子左上和右下加边框角 <!DOCTYPE html> <html lang="en"><head><meta charset=&quo ...

  6. LeetCode题解(1594):矩阵从左上移动到右下的最大非负积(Python)

    题目:原题链接(中等) 标签:贪心算法.动态规划 解法 时间复杂度 空间复杂度 执行用时 Ans 1 (Python) O(N×M)O(N×M)O(N×M) O(N×M)O(N×M)O(N×M) 44 ...

  7. 机器人网格行走-左上到右下的N种方法

    背景题目:有一个X*Y的矩阵网格,机器人在左上,每次只能向右或者向下行走,现求有多少种方法走到右下 对于这种问题,我们很容易想到用递归的方法解决 横向思考,当机器人往下走的时候,问题就转变成了(Y-1 ...

  8. html距离屏幕左侧,js+css使DIV始终居于屏幕中间 左下 左上 右上 右下的代码集合...

    随滚动条移动的层 正中... function sc1(){ document.getElementById("Javascript.Div1").style.top=(docum ...

  9. Java左上到右下,java – 如何从上到下然后从左到右填充Gri...

    您可以扩展GridLayout并仅覆盖一个方法 而不是int i = r * ncols c; use int i = c * nrows r;我认为这就够了. public void layoutC ...

最新文章

  1. 秀秀博客大赛50强的礼物
  2. 皮一皮:死要面子啊...
  3. matlab计算斜方差_协方差与协方差矩阵(附Matlab实现)
  4. java jpanel 缓冲画图_Java:Jpanel 缓冲区 图像
  5. arm-2014.05 编译三星内核错误 “not support ARM mode ‘smc 0’ ”
  6. php socketconnect连接失败_PHP设计模式之模板方法模式
  7. poj1470 LCA倍增法
  8. [USACO08NOV]时间管理Time Management
  9. mysql的读写分离工具_mysql 读写分离工具
  10. 操作DataTable
  11. InfoPath基础应用教程-1 设计一个简单的表单模板
  12. java虚拟机jvm下载_Java虚拟机(JVM)简介
  13. vue项目SEO优化
  14. RuoYi(若依) 微服务分离版 启动及常见问题总结
  15. 数据分析课堂笔记Day10(20221123)
  16. #大三狗的日常总结与反思03#
  17. 学习笔记 | NIPS 2021 regularization cocktail 调优的 MLPs 在表格数据上优于 GBDTs | Regularization is All Your Need
  18. 站长收入差距逐渐拉开 高收入站长稳步增加
  19. Emlog最新文章采集插件
  20. 有没有测试游戏天赋的软件,测测你的电竞天赋有多高游戏-抖音测测你的电竞天赋有多高官网版游戏V1.0...

热门文章

  1. pca降维的基本思想_一文读懂 PCA 降维算法
  2. eclipse没有日志_IPFS技术最新进展:抵抗eclipse攻击的能力
  3. 004_ZooKeeper客户端基础命令
  4. std string与线程安全_这才是现代C++单例模式简单又安全的实现
  5. Google Guava官方教程(中文版)
  6. Data Binding Library数据绑定框架
  7. linux 查明文密码,win10系统查看明文密码的操作方法
  8. php查询每个小时的数据,php – MySQL显示表中每小时的条目数
  9. nginx php unix负载,使用nginx配置多个php fastcgi负载均衡
  10. mysql查询索引like_mysql 索引与优化like查询