1
+ import java .util .Arrays ;
2
+
3
+ public class Solution3665 {
4
+ private static final int MOD = (int ) (1e9 + 7 );
5
+ private int [][] grid ;
6
+ private long [][][] memo ;
7
+
8
+ public int uniquePaths (int [][] grid ) {
9
+ this .grid = grid ;
10
+ int m = grid .length , n = grid [0 ].length ;
11
+ memo = new long [m ][n ][2 ];
12
+ for (int i = 0 ; i < m ; i ++) {
13
+ for (int j = 0 ; j < n ; j ++) {
14
+ Arrays .fill (memo [i ][j ], -1 );
15
+ }
16
+ }
17
+ return (int ) dfs (m - 1 , n - 1 , 0 );
18
+ }
19
+
20
+ private long dfs (int i , int j , int k ) {
21
+ if (i < 0 || j < 0 ) return 0 ; // 出界
22
+ if (i == 0 && j == 0 ) return 1 ; // 到达起点
23
+ if (memo [i ][j ][k ] != -1 ) return memo [i ][j ][k ];
24
+ long res ;
25
+ if (grid [i ][j ] == 0 ) { // 没有镜子,随便走
26
+ res = (dfs (i , j - 1 , 0 ) + dfs (i - 1 , j , 1 )) % MOD ;
27
+ } else if (k == 0 ) { // 从下边过来,反射到左边
28
+ res = dfs (i - 1 , j , 1 );
29
+ } else { // 从右边过来,反射到上边
30
+ res = dfs (i , j - 1 , 0 );
31
+ }
32
+ return memo [i ][j ][k ] = res ;
33
+ }
34
+ }
35
+ /*
36
+ 3665. 统计镜子反射路径数目
37
+ https://leetcode.cn/problems/twisted-mirror-path-count/description/
38
+
39
+ 第 164 场双周赛 T3。
40
+
41
+ 给你一个 m x n 的二进制网格 grid,其中:
42
+ - grid[i][j] == 0 表示一个空格子。
43
+ - grid[i][j] == 1 表示一面镜子。
44
+ 一个机器人从网格的左上角 (0, 0) 出发,想要到达右下角 (m - 1, n - 1)。它只能向 右 或向 下 移动。如果机器人试图移入一个有镜子的格子,它会在进入该格子前被 反射:
45
+ - 如果它试图向 右 移动进入镜子,它会被转向 下 方,并移动到镜子正下方的格子里。
46
+ - 如果它试图向 下 移动进入镜子,它会被转向 右 方,并移动到镜子正右方的格子里。
47
+ 如果这次反射会导致机器人移动到网格边界之外,则该路径被视为无效,不应被计数。
48
+ 返回从 (0, 0) 到 (m - 1, n - 1) 不同的有效路径数量。
49
+ 由于答案可能非常大,请将其返回对 10^9 + 7 取模 的结果。
50
+ 注意:如果一次反射将机器人移动到一个有镜子的格子,机器人会立即再次被反射。这次反射的方向取决于它进入该镜子的方向:如果它是向右移动进入的,它将被转向下方;如果它是向下移动进入的,它将被转向右方。
51
+ 提示:
52
+ m == grid.length
53
+ n == grid[i].length
54
+ 2 <= m, n <= 500
55
+ grid[i][j] 的值为 0 或 1。
56
+ grid[0][0] == grid[m - 1][n - 1] == 0
57
+
58
+ 记忆化搜索。
59
+ 时间复杂度 O(mn)。
60
+ */
0 commit comments