Skip to content

Commit ae31a7f

Browse files
authored
feat: add Rust solution for lc No.3651 (#4999)
1 parent d769511 commit ae31a7f

3 files changed

Lines changed: 269 additions & 2 deletions

File tree

solution/3600-3699/3651.Minimum Cost Path with Teleportations/README.md

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,41 @@ source: 第 163 场双周赛 Q4
138138

139139
<!-- solution:start -->
140140

141-
### 方法一
141+
### 方法一:动态规划
142+
143+
我们定义 $f[t][i][j]$ 表示使用了 $t$ 次传送到达单元格 $(i, j)$ 的最小成本,初始时 $f[0][0][0] = 0$,其余状态均为无穷大。
144+
145+
接下来,我们需要初始化 $f[0][i][j]$,在没有使用传送的情况下,我们只能通过向右或向下移动到达单元格 $(i, j)$。
146+
147+
如果 $i > 0$,则可以从上方单元格 $(i-1, j)$ 移动过来,更新状态为:
148+
149+
$$f[0][i][j] = \min(f[0][i][j], f[0][i-1][j] + grid[i][j])$$
150+
151+
如果 $j > 0$,则可以从左侧单元格 $(i, j-1)$ 移动过来,更新状态为:
152+
153+
$$f[0][i][j] = \min(f[0][i][j], f[0][i][j-1] + grid[i][j])$$
154+
155+
为了处理传送操作,我们需要将网格中的单元格按其值进行分组。我们使用一个哈希表 $g$,其中键为单元格的值,值为具有该值的单元格坐标列表。
156+
157+
对于每次传送 $t$ 从 $1$ 到 $k$,我们按照单元格值从大到小的顺序处理每个组。对于每个组中的单元格 $(i, j)$,我们首先更新一个全局最小值 $mn$,它表示在使用 $t-1$ 次传送时到达这些单元格的最小成本:
158+
159+
$$mn = \min(mn, f[t-1][i][j])$$
160+
161+
然后,我们将组中所有单元格的状态更新为 $mn$,表示通过传送到达这些单元格的最小成本。
162+
163+
接下来,我们再次遍历整个网格,更新 $f[t][i][j]$,考虑从上方或左侧单元格移动过来的情况:
164+
165+
如果 $i > 0$,则:
166+
167+
$$f[t][i][j] = \min(f[t][i][j], f[t][i-1][j] + grid[i][j])$$
168+
169+
如果 $j > 0$,则:
170+
171+
$$f[t][i][j] = \min(f[t][i][j], f[t][i][j-1] + grid[i][j])$$
172+
173+
最终,我们的答案是 $\min(f[t][m-1][n-1])$,其中 $t$ 从 $0$ 到 $k$。
174+
175+
时间复杂度 $O((k + \log mn) \times mn)$,空间复杂度 $O(k \times mn)$。其中 $m$ 和 $n$ 分别是网格的行数和列数,而 $k$ 是允许的最大传送次数。
142176

143177
<!-- tabs:start -->
144178

@@ -458,6 +492,74 @@ function minCost(grid: number[][], k: number): number {
458492
}
459493
```
460494

495+
#### Rust
496+
497+
```rust
498+
use std::collections::HashMap;
499+
500+
impl Solution {
501+
pub fn min_cost(grid: Vec<Vec<i32>>, k: i32) -> i32 {
502+
let m = grid.len();
503+
let n = grid[0].len();
504+
let k = k as usize;
505+
let inf: i32 = i32::MAX / 2;
506+
507+
let mut f = vec![vec![vec![inf; n]; m]; k + 1];
508+
509+
f[0][0][0] = 0;
510+
for i in 0..m {
511+
for j in 0..n {
512+
if i > 0 {
513+
f[0][i][j] = f[0][i][j].min(f[0][i - 1][j] + grid[i][j]);
514+
}
515+
if j > 0 {
516+
f[0][i][j] = f[0][i][j].min(f[0][i][j - 1] + grid[i][j]);
517+
}
518+
}
519+
}
520+
521+
let mut g: HashMap<i32, Vec<(usize, usize)>> = HashMap::new();
522+
for i in 0..m {
523+
for j in 0..n {
524+
g.entry(grid[i][j]).or_default().push((i, j));
525+
}
526+
}
527+
528+
let mut keys: Vec<i32> = g.keys().cloned().collect();
529+
keys.sort_by(|a, b| b.cmp(a));
530+
531+
for t in 1..=k {
532+
let mut mn = inf;
533+
for &key in &keys {
534+
let pos = &g[&key];
535+
for &(i, j) in pos {
536+
mn = mn.min(f[t - 1][i][j]);
537+
}
538+
for &(i, j) in pos {
539+
f[t][i][j] = mn;
540+
}
541+
}
542+
for i in 0..m {
543+
for j in 0..n {
544+
if i > 0 {
545+
f[t][i][j] = f[t][i][j].min(f[t][i - 1][j] + grid[i][j]);
546+
}
547+
if j > 0 {
548+
f[t][i][j] = f[t][i][j].min(f[t][i][j - 1] + grid[i][j]);
549+
}
550+
}
551+
}
552+
}
553+
554+
let mut ans = inf;
555+
for t in 0..=k {
556+
ans = ans.min(f[t][m - 1][n - 1]);
557+
}
558+
ans
559+
}
560+
}
561+
```
562+
461563
<!-- tabs:end -->
462564

463565
<!-- solution:end -->

solution/3600-3699/3651.Minimum Cost Path with Teleportations/README_EN.md

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,41 @@ source: Biweekly Contest 163 Q4
135135

136136
<!-- solution:start -->
137137

138-
### Solution 1
138+
### Solution 1: Dynamic Programming
139+
140+
We define $f[t][i][j]$ as the minimum cost to reach cell $(i, j)$ using exactly $t$ teleportations. Initially, $f[0][0][0] = 0$, and all other states are infinity.
141+
142+
First, we need to initialize $f[0][i][j]$. Without using teleportation, we can only reach cell $(i, j)$ by moving right or down.
143+
144+
If $i > 0$, we can move from the cell above $(i-1, j)$, updating the state as:
145+
146+
$$f[0][i][j] = \min(f[0][i][j], f[0][i-1][j] + grid[i][j])$$
147+
148+
If $j > 0$, we can move from the cell to the left $(i, j-1)$, updating the state as:
149+
150+
$$f[0][i][j] = \min(f[0][i][j], f[0][i][j-1] + grid[i][j])$$
151+
152+
To handle teleportation, we need to group the cells in the grid by their values. We use a hash map $g$, where the key is the cell value and the value is a list of coordinates of cells with that value.
153+
154+
For each teleportation count $t$ from $1$ to $k$, we process each group in descending order of cell values. For each cell $(i, j)$ in a group, we first update a global minimum $mn$, representing the minimum cost to reach these cells using $t-1$ teleportations:
155+
156+
$$mn = \min(mn, f[t-1][i][j])$$
157+
158+
Then, we update the state of all cells in the group to $mn$, representing the minimum cost to reach these cells via teleportation.
159+
160+
Next, we traverse the entire grid again to update $f[t][i][j]$, considering moves from the top or left cells:
161+
162+
If $i > 0$, then:
163+
164+
$$f[t][i][j] = \min(f[t][i][j], f[t][i-1][j] + grid[i][j])$$
165+
166+
If $j > 0$, then:
167+
168+
$$f[t][i][j] = \min(f[t][i][j], f[t][i][j-1] + grid[i][j])$$
169+
170+
Finally, our answer is $\min(f[t][m-1][n-1])$, where $t$ ranges from $0$ to $k$.
171+
172+
The time complexity is $O((k + \log mn) \times mn)$, and the space complexity is $O(k \times mn)$. Here, $m$ and $n$ are the number of rows and columns of the grid, respectively, and $k$ is the maximum allowed number of teleportations.
139173

140174
<!-- tabs:start -->
141175

@@ -455,6 +489,74 @@ function minCost(grid: number[][], k: number): number {
455489
}
456490
```
457491

492+
#### Rust
493+
494+
```rust
495+
use std::collections::HashMap;
496+
497+
impl Solution {
498+
pub fn min_cost(grid: Vec<Vec<i32>>, k: i32) -> i32 {
499+
let m = grid.len();
500+
let n = grid[0].len();
501+
let k = k as usize;
502+
let inf: i32 = i32::MAX / 2;
503+
504+
let mut f = vec![vec![vec![inf; n]; m]; k + 1];
505+
506+
f[0][0][0] = 0;
507+
for i in 0..m {
508+
for j in 0..n {
509+
if i > 0 {
510+
f[0][i][j] = f[0][i][j].min(f[0][i - 1][j] + grid[i][j]);
511+
}
512+
if j > 0 {
513+
f[0][i][j] = f[0][i][j].min(f[0][i][j - 1] + grid[i][j]);
514+
}
515+
}
516+
}
517+
518+
let mut g: HashMap<i32, Vec<(usize, usize)>> = HashMap::new();
519+
for i in 0..m {
520+
for j in 0..n {
521+
g.entry(grid[i][j]).or_default().push((i, j));
522+
}
523+
}
524+
525+
let mut keys: Vec<i32> = g.keys().cloned().collect();
526+
keys.sort_by(|a, b| b.cmp(a));
527+
528+
for t in 1..=k {
529+
let mut mn = inf;
530+
for &key in &keys {
531+
let pos = &g[&key];
532+
for &(i, j) in pos {
533+
mn = mn.min(f[t - 1][i][j]);
534+
}
535+
for &(i, j) in pos {
536+
f[t][i][j] = mn;
537+
}
538+
}
539+
for i in 0..m {
540+
for j in 0..n {
541+
if i > 0 {
542+
f[t][i][j] = f[t][i][j].min(f[t][i - 1][j] + grid[i][j]);
543+
}
544+
if j > 0 {
545+
f[t][i][j] = f[t][i][j].min(f[t][i][j - 1] + grid[i][j]);
546+
}
547+
}
548+
}
549+
}
550+
551+
let mut ans = inf;
552+
for t in 0..=k {
553+
ans = ans.min(f[t][m - 1][n - 1]);
554+
}
555+
ans
556+
}
557+
}
558+
```
559+
458560
<!-- tabs:end -->
459561

460562
<!-- solution:end -->
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::collections::HashMap;
2+
3+
impl Solution {
4+
pub fn min_cost(grid: Vec<Vec<i32>>, k: i32) -> i32 {
5+
let m = grid.len();
6+
let n = grid[0].len();
7+
let k = k as usize;
8+
let inf: i32 = i32::MAX / 2;
9+
10+
let mut f = vec![vec![vec![inf; n]; m]; k + 1];
11+
12+
f[0][0][0] = 0;
13+
for i in 0..m {
14+
for j in 0..n {
15+
if i > 0 {
16+
f[0][i][j] = f[0][i][j].min(f[0][i - 1][j] + grid[i][j]);
17+
}
18+
if j > 0 {
19+
f[0][i][j] = f[0][i][j].min(f[0][i][j - 1] + grid[i][j]);
20+
}
21+
}
22+
}
23+
24+
let mut g: HashMap<i32, Vec<(usize, usize)>> = HashMap::new();
25+
for i in 0..m {
26+
for j in 0..n {
27+
g.entry(grid[i][j]).or_default().push((i, j));
28+
}
29+
}
30+
31+
let mut keys: Vec<i32> = g.keys().cloned().collect();
32+
keys.sort_by(|a, b| b.cmp(a));
33+
34+
for t in 1..=k {
35+
let mut mn = inf;
36+
for &key in &keys {
37+
let pos = &g[&key];
38+
for &(i, j) in pos {
39+
mn = mn.min(f[t - 1][i][j]);
40+
}
41+
for &(i, j) in pos {
42+
f[t][i][j] = mn;
43+
}
44+
}
45+
for i in 0..m {
46+
for j in 0..n {
47+
if i > 0 {
48+
f[t][i][j] = f[t][i][j].min(f[t][i - 1][j] + grid[i][j]);
49+
}
50+
if j > 0 {
51+
f[t][i][j] = f[t][i][j].min(f[t][i][j - 1] + grid[i][j]);
52+
}
53+
}
54+
}
55+
}
56+
57+
let mut ans = inf;
58+
for t in 0..=k {
59+
ans = ans.min(f[t][m - 1][n - 1]);
60+
}
61+
ans
62+
}
63+
}

0 commit comments

Comments
 (0)