快速公交
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 56 ms, 内存: 17.8 MB
/*
* Problem: Xiao Kou plans to go to the Autumn City Market. Due to the crowd, his walking speed is affected:
* - Moving from station x to station x + 1 costs 'inc' time.
* - Moving from station x to station x - 1 costs 'dec' time.
* There are 'm' buses, numbered from 0 to m-1. Xiao Kou can take bus i to move from station x to station jump[i]*x at the cost of cost[i].
* Xiao Kou can take any bus any number of times. The start station is 0 and the target station is 'target'.
* Return the minimum time Xiao Kou needs to reach the target station, modulo 1000000007 (1e9 + 7).
* Note: Xiao Kou can reach a station number greater than 'target' during the process.
*/
import java.util.*;
import java.util.stream.Stream;
public class MinTimeToTargetStream {
public int minCost(int target, int inc, int dec, int[] jump, int[] cost) {
long mod = 1000000007;
Map<Long, Long> dp = new HashMap<>();
dp.put(0L, 0L);
PriorityQueue<long[]> pq = new PriorityQueue<>(Comparator.comparingLong(a -> a[1]));
pq.add(new long[]{0, 0});
while (!pq.isEmpty()) {
long[] curr = pq.poll();
long pos = curr[0], time = curr[1];
if (pos == target) return (int)(time % mod);
if (dp.getOrDefault(pos, Long.MAX_VALUE) < time) continue;
Stream.of(new long[]{pos + 1, time + inc},
pos > 0 ? new long[]{pos - 1, time + dec} : null)
.filter(Objects::nonNull)
.forEach(next -> {
if (!dp.containsKey(next[0]) || dp.get(next[0]) > next[1]) {
dp.put(next[0], next[1]);
pq.add(next);
}
});
for (int i = 0; i < jump.length; i++) {
long newPos = pos * jump[i];
if (!dp.containsKey(newPos) || dp.get(newPos) > time + cost[i]) {
dp.put(newPos, time + cost[i]);
pq.add(new long[]{newPos, time + cost[i]});
}
}
}
return -1;
}
}
解释
方法:
本题解采用了优先队列(最小堆)结合广度优先搜索的方法来寻找到达目标站点的最小花费。初始时,将目标站点放入优先队列,代表从目标站点逆向回到起点的代价为零(逆向思维)。然后逐渐将所有可能的站点及其花费压入优先队列。对于每个站点,计算直接步行到起点的花费,以及通过公交车跳跃后的新站点和对应花费。每次从优先队列中取出当前花费最小的站点,更新答案,并检查是否已到起点。如果达到起点站,记录总花费并结束搜索。否则,继续探索下一跳的可能站点。利用visited_stations集合避免重复处理同一站点,以优化搜索效率。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
题解中提到使用逆向思维,即从目标站点逆向回到起点,这种方法是如何确保找到最小花费的路径的?
▷🦆
为什么在处理过程中当`total_cost`大于已知的最小值`ans`时,可以安全地终止处理当前站点?
▷🦆
题解中使用了优先队列(最小堆),这种数据结构在此问题中的主要优势是什么?
▷