diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README.md b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README.md index f06cbb9744d3b..e93e2f289a70d 100644 --- a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README.md +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README.md @@ -81,32 +81,153 @@ tags: -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i][j]$ 表示经过 $i$ 分钟,从城市 $0$ 到达城市 $j$ 的最小花费。初始时 $f[0][0] = \textit{passingFees}[0]$,其余的 $f[0][j] = +\infty$。 + +接下来,我们在 $[1, \textit{maxTime}]$ 的时间范围内,遍历所有的边,对于每一条边 $(x, y, t)$,如果 $t \leq i$,那么我们: + +- 可以先经过 $i - t$ 分钟,从城市 $0$ 到达城市 $y$,然后再经过 $t$ 分钟,从城市 $y$ 到达城市 $x$,再加上到达城市 $x$ 的通行费,即 $f[i][x] = \min(f[i][x], f[i - t][y] + \textit{passingFees}[x])$; +- 也可以先经过 $i - t$ 分钟,从城市 $0$ 到达城市 $x$,然后再经过 $t$ 分钟,从城市 $x$ 到达城市 $y$,再加上到达城市 $y$ 的通行费,即 $f[i][y] = \min(f[i][y], f[i - t][x] + \textit{passingFees}[y])$。 + +最终答案即为 $\min\{f[i][n - 1]\}$,其中 $i \in [0, \textit{maxTime}]$。如果答案为 $+\infty$,则返回 $-1$。 + +时间复杂度 $O(\textit{maxTime} \times (m + n))$,其中 $m$ 和 $n$ 分别是边的数量和城市的数量。空间复杂度 $O(\textit{maxTime} \times n)$。 #### Python3 ```python - +class Solution: + def minCost( + self, maxTime: int, edges: List[List[int]], passingFees: List[int] + ) -> int: + m, n = maxTime, len(passingFees) + f = [[inf] * n for _ in range(m + 1)] + f[0][0] = passingFees[0] + for i in range(1, m + 1): + for x, y, t in edges: + if t <= i: + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]) + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]) + ans = min(f[i][n - 1] for i in range(m + 1)) + return ans if ans < inf else -1 ``` #### Java ```java - +class Solution { + public int minCost(int maxTime, int[][] edges, int[] passingFees) { + int m = maxTime, n = passingFees.length; + int[][] f = new int[m + 1][n]; + final int inf = 1 << 30; + for (var g : f) { + Arrays.fill(g, inf); + } + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (var e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 0; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minCost(int maxTime, vector>& edges, vector& passingFees) { + int m = maxTime, n = passingFees.size(); + const int inf = 1 << 30; + vector> f(m + 1, vector(n, inf)); + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (const auto& e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 1; i <= m; ++i) { + ans = min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +}; ``` #### Go ```go +func minCost(maxTime int, edges [][]int, passingFees []int) int { + m, n := maxTime, len(passingFees) + f := make([][]int, m+1) + const inf int = 1 << 30 + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = inf + } + } + f[0][0] = passingFees[0] + for i := 1; i <= m; i++ { + for _, e := range edges { + x, y, t := e[0], e[1], e[2] + if t <= i { + f[i][x] = min(f[i][x], f[i-t][y]+passingFees[x]) + f[i][y] = min(f[i][y], f[i-t][x]+passingFees[y]) + } + } + } + ans := inf + for i := 1; i <= m; i++ { + ans = min(ans, f[i][n-1]) + } + if ans == inf { + return -1 + } + return ans +} +``` +#### TypeScript + +```ts +function minCost(maxTime: number, edges: number[][], passingFees: number[]): number { + const [m, n] = [maxTime, passingFees.length]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n).fill(Infinity)); + f[0][0] = passingFees[0]; + for (let i = 1; i <= m; ++i) { + for (const [x, y, t] of edges) { + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + let ans = Infinity; + for (let i = 1; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans === Infinity ? -1 : ans; +} ``` diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README_EN.md b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README_EN.md index 246779fdf51d0..0a02e4da60a51 100644 --- a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README_EN.md +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/README_EN.md @@ -79,32 +79,153 @@ You cannot take path 0 -> 1 -> 2 -> 5 since it would take too long. -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i][j]$ to represent the minimum cost to reach city $j$ from city $0$ after $i$ minutes. Initially, $f[0][0] = \textit{passingFees}[0]$, and the rest $f[0][j] = +\infty$. + +Next, within the time range $[1, \textit{maxTime}]$, we traverse all edges. For each edge $(x, y, t)$, if $t \leq i$, then we: + +- Can first spend $i - t$ minutes to reach city $y$ from city $0$, then spend $t$ minutes to reach city $x$ from city $y$, and add the passing fee to reach city $x$, i.e., $f[i][x] = \min(f[i][x], f[i - t][y] + \textit{passingFees}[x])$; +- Can also first spend $i - t$ minutes to reach city $x$ from city $0$, then spend $t$ minutes to reach city $y$ from city $x$, and add the passing fee to reach city $y$, i.e., $f[i][y] = \min(f[i][y], f[i - t][x] + \textit{passingFees}[y])$. + +The final answer is $\min\{f[i][n - 1]\}$, where $i \in [0, \textit{maxTime}]$. If the answer is $+\infty$, return $-1$. + +The time complexity is $O(\textit{maxTime} \times (m + n))$, where $m$ and $n$ are the number of edges and cities, respectively. The space complexity is $O(\textit{maxTime} \times n)$. #### Python3 ```python - +class Solution: + def minCost( + self, maxTime: int, edges: List[List[int]], passingFees: List[int] + ) -> int: + m, n = maxTime, len(passingFees) + f = [[inf] * n for _ in range(m + 1)] + f[0][0] = passingFees[0] + for i in range(1, m + 1): + for x, y, t in edges: + if t <= i: + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]) + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]) + ans = min(f[i][n - 1] for i in range(m + 1)) + return ans if ans < inf else -1 ``` #### Java ```java - +class Solution { + public int minCost(int maxTime, int[][] edges, int[] passingFees) { + int m = maxTime, n = passingFees.length; + int[][] f = new int[m + 1][n]; + final int inf = 1 << 30; + for (var g : f) { + Arrays.fill(g, inf); + } + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (var e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 0; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minCost(int maxTime, vector>& edges, vector& passingFees) { + int m = maxTime, n = passingFees.size(); + const int inf = 1 << 30; + vector> f(m + 1, vector(n, inf)); + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (const auto& e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 1; i <= m; ++i) { + ans = min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +}; ``` #### Go ```go +func minCost(maxTime int, edges [][]int, passingFees []int) int { + m, n := maxTime, len(passingFees) + f := make([][]int, m+1) + const inf int = 1 << 30 + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = inf + } + } + f[0][0] = passingFees[0] + for i := 1; i <= m; i++ { + for _, e := range edges { + x, y, t := e[0], e[1], e[2] + if t <= i { + f[i][x] = min(f[i][x], f[i-t][y]+passingFees[x]) + f[i][y] = min(f[i][y], f[i-t][x]+passingFees[y]) + } + } + } + ans := inf + for i := 1; i <= m; i++ { + ans = min(ans, f[i][n-1]) + } + if ans == inf { + return -1 + } + return ans +} +``` +#### TypeScript + +```ts +function minCost(maxTime: number, edges: number[][], passingFees: number[]): number { + const [m, n] = [maxTime, passingFees.length]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n).fill(Infinity)); + f[0][0] = passingFees[0]; + for (let i = 1; i <= m; ++i) { + for (const [x, y, t] of edges) { + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + let ans = Infinity; + for (let i = 1; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans === Infinity ? -1 : ans; +} ``` diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.cpp b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.cpp new file mode 100644 index 0000000000000..b092809758334 --- /dev/null +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + int minCost(int maxTime, vector>& edges, vector& passingFees) { + int m = maxTime, n = passingFees.size(); + const int inf = 1 << 30; + vector> f(m + 1, vector(n, inf)); + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (const auto& e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 1; i <= m; ++i) { + ans = min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +}; diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.go b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.go new file mode 100644 index 0000000000000..9a98b4d9a4dfa --- /dev/null +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.go @@ -0,0 +1,29 @@ +func minCost(maxTime int, edges [][]int, passingFees []int) int { + m, n := maxTime, len(passingFees) + f := make([][]int, m+1) + const inf int = 1 << 30 + for i := range f { + f[i] = make([]int, n) + for j := range f[i] { + f[i][j] = inf + } + } + f[0][0] = passingFees[0] + for i := 1; i <= m; i++ { + for _, e := range edges { + x, y, t := e[0], e[1], e[2] + if t <= i { + f[i][x] = min(f[i][x], f[i-t][y]+passingFees[x]) + f[i][y] = min(f[i][y], f[i-t][x]+passingFees[y]) + } + } + } + ans := inf + for i := 1; i <= m; i++ { + ans = min(ans, f[i][n-1]) + } + if ans == inf { + return -1 + } + return ans +} diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.java b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.java new file mode 100644 index 0000000000000..054a9ba9cbcd2 --- /dev/null +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.java @@ -0,0 +1,25 @@ +class Solution { + public int minCost(int maxTime, int[][] edges, int[] passingFees) { + int m = maxTime, n = passingFees.length; + int[][] f = new int[m + 1][n]; + final int inf = 1 << 30; + for (var g : f) { + Arrays.fill(g, inf); + } + f[0][0] = passingFees[0]; + for (int i = 1; i <= m; ++i) { + for (var e : edges) { + int x = e[0], y = e[1], t = e[2]; + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + int ans = inf; + for (int i = 0; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans == inf ? -1 : ans; + } +} diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.py b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.py new file mode 100644 index 0000000000000..df4f3d0f17a61 --- /dev/null +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.py @@ -0,0 +1,14 @@ +class Solution: + def minCost( + self, maxTime: int, edges: List[List[int]], passingFees: List[int] + ) -> int: + m, n = maxTime, len(passingFees) + f = [[inf] * n for _ in range(m + 1)] + f[0][0] = passingFees[0] + for i in range(1, m + 1): + for x, y, t in edges: + if t <= i: + f[i][x] = min(f[i][x], f[i - t][y] + passingFees[x]) + f[i][y] = min(f[i][y], f[i - t][x] + passingFees[y]) + ans = min(f[i][n - 1] for i in range(m + 1)) + return ans if ans < inf else -1 diff --git a/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.ts b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.ts new file mode 100644 index 0000000000000..7b20f47397724 --- /dev/null +++ b/solution/1900-1999/1928.Minimum Cost to Reach Destination in Time/Solution.ts @@ -0,0 +1,18 @@ +function minCost(maxTime: number, edges: number[][], passingFees: number[]): number { + const [m, n] = [maxTime, passingFees.length]; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n).fill(Infinity)); + f[0][0] = passingFees[0]; + for (let i = 1; i <= m; ++i) { + for (const [x, y, t] of edges) { + if (t <= i) { + f[i][x] = Math.min(f[i][x], f[i - t][y] + passingFees[x]); + f[i][y] = Math.min(f[i][y], f[i - t][x] + passingFees[y]); + } + } + } + let ans = Infinity; + for (let i = 1; i <= m; ++i) { + ans = Math.min(ans, f[i][n - 1]); + } + return ans === Infinity ? -1 : ans; +}