Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 710f737

Browse files
feat: add solutions to lc problem: No.1883 (doocs#1636)
No.1883.Minimum Skips to Arrive at Meeting On Time
1 parent d10c94b commit 710f737

File tree

7 files changed

+391
-110
lines changed

7 files changed

+391
-110
lines changed

‎solution/1800-1899/1883.Minimum Skips to Arrive at Meeting On Time/README.md‎

Lines changed: 142 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,21 @@
6969

7070
<!-- 这里可写通用的实现逻辑 -->
7171

72-
"动态规划"实现。
72+
**方法一:动态规划**
7373

74-
定义 `dp[i][j]` 表示前 i 段道路,跳过了 j 次的最短路程(耗时也一样)
74+
我们定义 $f[i][j]$ 表示考虑前 $i$ 条道路,恰好跳过 $j$ 次休息时间的最短用时。初始时 $f[0][0]=0,ドル其余 $f[i][j]=\infty$
7575

76-
考虑最后一段道路 `dist[i - 1]` 是否跳过:
76+
由于我们可以选择跳过或者不跳过第 $i$ 条道路的休息时间,因此我们可以列出状态转移方程:
7777

78-
- 若没有跳过,那么 `dp[i][j] = ⌈dp[i - 1][j] + dist[i - 1] / speed⌉`
79-
- 若跳过,那么 `dp[i][j] = dp[i - 1][j - 1] + dist[i - 1] / speed`
78+
$$
79+
f[i][j]=\min\left\{\begin{aligned} \lceil f[i-1][j]+\frac{d_i}{s}\rceil & \text{不跳过第 $i$ 条道路的休息时间} \\ f[i-1][j-1]+\frac{d_i}{s} & \text{跳过第 $i$ 条道路的休息时间} \end{aligned}\right.
80+
$$
8081

81-
综合两种情况,`dp[i][j] = min{⌈dp[i - 1][j] + dist[i - 1] / speed⌉, dp[i - 1][j - 1] + dist[i - 1] / speed}`
82+
其中 $\lceil x\rceil$ 表示将 $x$ 向上取整。需要注意的是,由于我们需要保证恰好跳过 $j$ 次休息时间,因此我们必须有 $j\le i$;另外,如果 $j=0,ドル不能跳过任何休息时间。
83+
84+
由于浮点数运算以及向上取整运算可能会带来精度误差,因此我们引入一个常量 $eps = 10^{-8}$ 表示一个极小的正实数,在浮点数取整前先减去 $eps,ドル最后在比较 $f[n][j]$ 和 $hoursBefore$ 时,需要加上 $eps$。
85+
86+
时间复杂度 $O(n^2),ドル空间复杂度 $O(n^2)$。其中 $n$ 是道路的数量。
8287

8388
<!-- tabs:start -->
8489

@@ -90,22 +95,36 @@
9095
class Solution:
9196
def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int:
9297
n = len(dist)
93-
dp = [[inf] * (n + 1) for _ in range(n + 1)]
94-
dp[0][0] = 0
95-
for i in range(1, n + 1):
98+
f = [[inf] * (n + 1) for _ in range(n + 1)]
99+
f[0][0] = 0
100+
eps = 1e-8
101+
for i, x in enumerate(dist, 1):
102+
for j in range(i + 1):
103+
if j < i:
104+
f[i][j] = min(f[i][j], ceil(f[i - 1][j] + x / speed - eps))
105+
if j:
106+
f[i][j] = min(f[i][j], f[i - 1][j - 1] + x / speed)
107+
for j in range(n + 1):
108+
if f[n][j] <= hoursBefore + eps:
109+
return j
110+
return -1
111+
```
112+
113+
```python
114+
class Solution:
115+
def minSkips(self, dist: List[int], speed: int, hoursBefore: int) -> int:
116+
n = len(dist)
117+
f = [[inf] * (n + 1) for _ in range(n + 1)]
118+
f[0][0] = 0
119+
for i, x in enumerate(dist, 1):
96120
for j in range(i + 1):
97-
if i != j:
98-
# 没有跳过
99-
dp[i][j] = min(
100-
dp[i][j],
101-
((dp[i - 1][j] + dist[i - 1] - 1) // speed + 1) * speed,
102-
)
103-
if j > 0:
104-
# 跳过
105-
dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + dist[i - 1])
106-
for i in range(n + 1):
107-
if dp[n][i] <= hoursBefore * speed:
108-
return i
121+
if j < i:
122+
f[i][j] = min(f[i][j], ((f[i - 1][j] + x - 1) // speed + 1) * speed)
123+
if j:
124+
f[i][j] = min(f[i][j], f[i - 1][j - 1] + x)
125+
for j in range(n + 1):
126+
if f[n][j] <= hoursBefore * speed:
127+
return j
109128
return -1
110129
```
111130

@@ -117,36 +136,123 @@ class Solution:
117136
class Solution {
118137
public int minSkips(int[] dist, int speed, int hoursBefore) {
119138
int n = dist.length;
120-
int[][] dp = new int[n + 1][n + 1];
121-
for (int i = 0; i <= n; ++i) {
122-
for (int j = 0; j <= n; ++j) {
123-
dp[i][j] = Integer.MAX_VALUE;
124-
}
139+
double[][] f = new double[n + 1][n + 1];
140+
for (int i = 0; i <= n; i++) {
141+
Arrays.fill(f[i], 1e20);
125142
}
126-
dp[0][0] = 0;
143+
f[0][0] = 0;
144+
double eps = 1e-8;
127145
for (int i = 1; i <= n; ++i) {
128146
for (int j = 0; j <= i; ++j) {
129-
if (i != j) {
130-
// 没有跳过
131-
dp[i][j] = Math.min(
132-
dp[i][j], ((dp[i - 1][j] + dist[i - 1] - 1) / speed + 1) * speed);
147+
if (j < i) {
148+
f[i][j] = Math.min(
149+
f[i][j], Math.ceil(f[i - 1][j]) + 1.0 * dist[i - 1] / speed - eps);
133150
}
134151
if (j > 0) {
135-
// 跳过
136-
dp[i][j] = Math.min(dp[i][j], dp[i - 1][j - 1] + dist[i - 1]);
152+
f[i][j] = Math.min(f[i][j], f[i - 1][j - 1] + 1.0 * dist[i - 1] / speed);
137153
}
138154
}
139155
}
140-
for (int i = 0; i <= n; ++i) {
141-
if (dp[n][i] <= hoursBefore * speed) {
142-
return i;
156+
for (int j = 0; j <= n; ++j) {
157+
if (f[n][j] <= hoursBefore + eps) {
158+
return j;
143159
}
144160
}
145161
return -1;
146162
}
147163
}
148164
```
149165

166+
### **C++**
167+
168+
```cpp
169+
class Solution {
170+
public:
171+
int minSkips(vector<int>& dist, int speed, int hoursBefore) {
172+
int n = dist.size();
173+
vector<vector<double>> f(n + 1, vector<double>(n + 1, 1e20));
174+
f[0][0] = 0;
175+
double eps = 1e-8;
176+
for (int i = 1; i <= n; ++i) {
177+
for (int j = 0; j <= i; ++j) {
178+
if (j < i) {
179+
f[i][j] = min(f[i][j], ceil(f[i - 1][j] + dist[i - 1] * 1.0 / speed - eps));
180+
}
181+
if (j) {
182+
f[i][j] = min(f[i][j], f[i - 1][j - 1] + dist[i - 1] * 1.0 / speed);
183+
}
184+
}
185+
}
186+
for (int j = 0; j <= n; ++j) {
187+
if (f[n][j] <= hoursBefore + eps) {
188+
return j;
189+
}
190+
}
191+
return -1;
192+
}
193+
};
194+
```
195+
196+
### **Go**
197+
198+
```go
199+
func minSkips(dist []int, speed int, hoursBefore int) int {
200+
n := len(dist)
201+
f := make([][]float64, n+1)
202+
for i := range f {
203+
f[i] = make([]float64, n+1)
204+
for j := range f[i] {
205+
f[i][j] = 1e20
206+
}
207+
}
208+
f[0][0] = 0
209+
eps := 1e-8
210+
for i := 1; i <= n; i++ {
211+
for j := 0; j <= i; j++ {
212+
if j < i {
213+
f[i][j] = math.Min(f[i][j], math.Ceil(f[i-1][j]+float64(dist[i-1])/float64(speed)-eps))
214+
}
215+
if j > 0 {
216+
f[i][j] = math.Min(f[i][j], f[i-1][j-1]+float64(dist[i-1])/float64(speed))
217+
}
218+
}
219+
}
220+
for j := 0; j <= n; j++ {
221+
if f[n][j] <= float64(hoursBefore) {
222+
return j
223+
}
224+
}
225+
return -1
226+
}
227+
```
228+
229+
### **TypeScript**
230+
231+
```ts
232+
function minSkips(dist: number[], speed: number, hoursBefore: number): number {
233+
const n = dist.length;
234+
const f = Array.from({ length: n + 1 }, () => Array.from({ length: n + 1 }, () => Infinity));
235+
f[0][0] = 0;
236+
const eps = 1e-8;
237+
for (let i = 1; i <= n; ++i) {
238+
for (let j = 0; j <= i; ++j) {
239+
if (j < i) {
240+
f[i][j] = Math.min(f[i][j], Math.ceil(f[i - 1][j] + dist[i - 1] / speed - eps));
241+
}
242+
if (j) {
243+
f[i][j] = Math.min(f[i][j], f[i - 1][j - 1] + dist[i - 1] / speed);
244+
}
245+
}
246+
}
247+
for (let j = 0; j <= n; ++j) {
248+
if (f[n][j] <= hoursBefore + eps) {
249+
return j;
250+
}
251+
}
252+
return -1;
253+
}
254+
```
255+
150256
### **...**
151257

152258
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /