rustgym/leetcode/
_871_minimum_number_of_refueling_stops.rs1struct Solution;
2
3use std::cmp::Reverse;
4use std::collections::BinaryHeap;
5use std::collections::HashMap;
6
7impl Solution {
8 fn min_refuel_stops(target: i32, start_fuel: i32, mut stations: Vec<Vec<i32>>) -> i32 {
9 let mut queue: BinaryHeap<(Reverse<usize>, usize, i32)> = BinaryHeap::new();
10 stations.push(vec![target, 0]);
11 let n = stations.len();
12 let fuel = start_fuel - stations[0][0];
13 let mut states: HashMap<(usize, usize), i32> = HashMap::new();
14 if fuel >= 0 {
15 states.insert((0, 0), fuel);
16 queue.push((Reverse(0), 0, fuel));
17 }
18 while let Some((Reverse(stop), i, fuel)) = queue.pop() {
19 if i == n - 1 {
20 return stop as i32;
21 }
22 let dist = stations[i + 1][0] - stations[i][0];
23 let take = fuel + stations[i][1] - dist;
24 let skip = fuel - dist;
25 for &(s, f) in &[(stop + 1, take), (stop, skip)] {
26 if f < 0 {
27 continue;
28 }
29 if let Some(&max_f) = states.get(&(i + 1, s)) {
30 if max_f >= f {
31 continue;
32 }
33 }
34 *states.entry((i + 1, s)).or_default() = f;
35 queue.push((Reverse(s), i + 1, f));
36 }
37 }
38 -1
39 }
40}
41
42#[test]
43fn test() {
44 let target = 1;
45 let start_fuel = 1;
46 let stations = vec_vec_i32![];
47 let res = 0;
48 assert_eq!(
49 Solution::min_refuel_stops(target, start_fuel, stations),
50 res
51 );
52 let target = 100;
53 let start_fuel = 1;
54 let stations = vec_vec_i32![[10, 100]];
55 let res = -1;
56 assert_eq!(
57 Solution::min_refuel_stops(target, start_fuel, stations),
58 res
59 );
60 let target = 100;
61 let start_fuel = 10;
62 let stations = vec_vec_i32![[10, 60], [20, 30], [30, 30], [60, 40]];
63 let res = 2;
64 assert_eq!(
65 Solution::min_refuel_stops(target, start_fuel, stations),
66 res
67 );
68}