1
+ import java .util .Arrays ;
2
+
3
+ public class Solution3651 {
4
+ public int minCost (int [][] grid , int k ) {
5
+ int m = grid .length ;
6
+ int n = grid [0 ].length ;
7
+ int maxVal = 10000 ;
8
+ int [][][] best = new int [k + 1 ][m ][n ];
9
+ for (int t = 0 ; t <= k ; t ++) {
10
+ for (int i = 0 ; i < m ; i ++) {
11
+ Arrays .fill (best [t ][i ], Integer .MAX_VALUE );
12
+ }
13
+ }
14
+ best [0 ][0 ][0 ] = 0 ;
15
+
16
+ for (int t = 0 ; t <= k ; t ++) {
17
+ for (int i = 0 ; i < m ; i ++) {
18
+ for (int j = 0 ; j < n ; j ++) {
19
+ if (best [t ][i ][j ] == Integer .MAX_VALUE )
20
+ continue ;
21
+ if (j + 1 < n ) {
22
+ int newCost = best [t ][i ][j ] + grid [i ][j + 1 ];
23
+ if (newCost < best [t ][i ][j + 1 ]) {
24
+ best [t ][i ][j + 1 ] = newCost ;
25
+ }
26
+ }
27
+ if (i + 1 < m ) {
28
+ int newCost = best [t ][i ][j ] + grid [i + 1 ][j ];
29
+ if (newCost < best [t ][i + 1 ][j ]) {
30
+ best [t ][i + 1 ][j ] = newCost ;
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ int [] minCostForValue = new int [maxVal + 1 ];
37
+ Arrays .fill (minCostForValue , Integer .MAX_VALUE );
38
+ for (int i = 0 ; i < m ; i ++) {
39
+ for (int j = 0 ; j < n ; j ++) {
40
+ if (best [t ][i ][j ] != Integer .MAX_VALUE ) {
41
+ int val = grid [i ][j ];
42
+ if (best [t ][i ][j ] < minCostForValue [val ]) {
43
+ minCostForValue [val ] = best [t ][i ][j ];
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ int [] minSuffix = new int [maxVal + 1 ];
50
+ minSuffix [maxVal ] = minCostForValue [maxVal ];
51
+ for (int v = maxVal - 1 ; v >= 0 ; v --) {
52
+ if (minCostForValue [v ] < minSuffix [v + 1 ]) {
53
+ minSuffix [v ] = minCostForValue [v ];
54
+ } else {
55
+ minSuffix [v ] = minSuffix [v + 1 ];
56
+ }
57
+ }
58
+
59
+ if (t < k ) {
60
+ for (int i = 0 ; i < m ; i ++) {
61
+ for (int j = 0 ; j < n ; j ++) {
62
+ int val = grid [i ][j ];
63
+ if (minSuffix [val ] < best [t + 1 ][i ][j ]) {
64
+ best [t + 1 ][i ][j ] = minSuffix [val ];
65
+ }
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ int ans = Integer .MAX_VALUE ;
72
+ for (int t = 0 ; t <= k ; t ++) {
73
+ if (best [t ][m - 1 ][n - 1 ] < ans ) {
74
+ ans = best [t ][m - 1 ][n - 1 ];
75
+ }
76
+ }
77
+ return ans ;
78
+ }
79
+ }
80
+ /*
81
+ 3651. 带传送的最小路径成本
82
+ https://leetcode.cn/problems/minimum-cost-path-with-teleportations/description/
83
+
84
+ 第 163 场双周赛 T4。
85
+
86
+ 给你一个 m x n 的二维整数数组 grid 和一个整数 k。你从左上角的单元格 (0, 0) 出发,目标是到达右下角的单元格 (m - 1, n - 1)。
87
+ 有两种移动方式可用:
88
+ - 普通移动:你可以从当前单元格 (i, j) 向右或向下移动,即移动到 (i, j + 1)(右)或 (i + 1, j)(下)。成本为目标单元格的值。
89
+ - 传送:你可以从任意单元格 (i, j) 传送到任意满足 grid[x][y] <= grid[i][j] 的单元格 (x, y);此移动的成本为 0。你最多可以传送 k 次。
90
+ 返回从 (0, 0) 到达单元格 (m - 1, n - 1) 的 最小 总成本。
91
+ 提示:
92
+ 2 <= m, n <= 80
93
+ m == grid.length
94
+ n == grid[i].length
95
+ 0 <= grid[i][j] <= 10^4
96
+ 0 <= k <= 10
97
+
98
+ DP + 后缀最小值优化。
99
+ https://chat.deepseek.com/a/chat/s/1bf4a47a-246a-4ed2-b511-34da3bc5ff8d
100
+ 时间复杂度 O((mn+U)k)。
101
+ rating 2410 (clist.by)
102
+ */
0 commit comments