现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。
给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
测试样例:
[[0,1,0],[2,0,0]],2,3
返回:2
思路:典型的动态规划题,以1在左上角,2在右上角为例。1只能向下或者向右走。先初始化1所在的列,遇见-1之前全部赋值为1,遇见0之后全赋值为0,同理再初始化行。
边界以2为准。再根据 dp[row][col]=dp[row-1][col]+dp[row][col-1] 进行赋值,直到到达商店,直接返回该处的值即可。
0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | -1 | 0 | 0 |
0 | 0 | 2 | 0 |
-> | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 0 | |
0 | 1 | 0 | 0 | |
0 | -1 | 0 | 0 | |
0 | 0 | 2 | 0 |
0 | 1 | 1 | 0 | |
0 | 1 | 2 | 0 | |
-> | 0 | 1 | 3 | 0 |
0 | 0 | 3 | 0 | |
0 | 0 | 3 | 0 |
1 public int countPath(int[][] map, int n, int m) { 2 int hori = 0, vert = 0; 3 Integer manaRow = 0, manaCol = 0, stroeRow = 0, storeCol = 0; 4 // 找到经理和商家的位置 5 for (int row = 0; row < n; row++) { 6 for (int col = 0; col < m; col++) { 7 if (map[row][col] == 1) { 8 manaRow = row; 9 manaCol = col; 10 } else if (map[row][col] == 2) { 11 stroeRow = row; 12 storeCol = col; 13 } 14 } 15 } 16 vert = stroeRow.compareTo(manaRow); 17 hori = storeCol.compareTo(manaCol); 18 // 初始化经理所在的列 19 for (int row = manaRow + vert; row != stroeRow + vert; row += vert) { 20 map[row][manaCol] = map[row][manaCol] == -1 ? 0 21 : map[row - vert][manaCol]; 22 } 23 24 // 初始化经理所在的行 25 for (int col = manaCol + hori; col != storeCol + hori; col += hori) { 26 map[manaRow][col] = map[manaRow][col] == -1 ? 0 : map[manaRow][col 27 - hori]; 28 } 29 30 for (int col = manaCol + hori; col != storeCol + hori; col += hori) { 31 for (int row = manaRow + vert; row != stroeRow + vert; row += vert) { 32 map[row][col] = map[row - hori][col] + map[row][col - vert]; 33 } 34 } 35 return map[stroeRow][storeCol]; 36 }