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 0a017c9

Browse files
feat: add solutions to lc problem: No.3466 (#4108)
No.3466.Maximum Coin Collection
1 parent 4ea435c commit 0a017c9

File tree

13 files changed

+798
-11
lines changed

13 files changed

+798
-11
lines changed

‎solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ tags:
3333
<strong>输入:</strong>arr = [5,4,3,2,1]
3434
<strong>输出:</strong>1
3535
<strong>解释:</strong>
36-
将数组分成2块或者更多块,都无法得到所需的结果。
37-
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
36+
将数组分成2块或者更多块,都无法得到所需的结果。
37+
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
3838
</pre>
3939

4040
<p><strong class="example">示例 2:</strong></p>
@@ -43,8 +43,8 @@ tags:
4343
<strong>输入:</strong>arr = [2,1,3,4,4]
4444
<strong>输出:</strong>4
4545
<strong>解释:</strong>
46-
可以把它分成两块,例如 [2, 1], [3, 4, 4]。
47-
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
46+
可以把它分成两块,例如 [2, 1], [3, 4, 4]。
47+
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
4848
</pre>
4949

5050
<p>&nbsp;</p>

‎solution/0700-0799/0779.K-th Symbol in Grammar/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ tags:
4040
<pre>
4141
<strong>输入:</strong> n = 2, k = 1
4242
<strong>输出:</strong> 0
43-
<strong>解释:</strong>
44-
第一行: 0
43+
<strong>解释:</strong>
44+
第一行: 0
4545
第二行: <u>0</u>1
4646
</pre>
4747

‎solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ tags:
4040
<pre>
4141
<strong>Input:</strong> n = 2, k = 1
4242
<strong>Output:</strong> 0
43-
<strong>Explanation:</strong>
43+
<strong>Explanation:</strong>
4444
row 1: 0
4545
row 2: <u>0</u>1
4646
</pre>
@@ -50,7 +50,7 @@ row 2: <u>0</u>1
5050
<pre>
5151
<strong>Input:</strong> n = 2, k = 2
5252
<strong>Output:</strong> 1
53-
<strong>Explanation:</strong>
53+
<strong>Explanation:</strong>
5454
row 1: 0
5555
row 2: 0<u>1</u>
5656
</pre>

‎solution/0700-0799/0781.Rabbits in Forest/README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ tags:
3131
<strong>输入:</strong>answers = [1,1,2]
3232
<strong>输出:</strong>5
3333
<strong>解释:</strong>
34-
两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
34+
两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
3535
之后回答了 "2" 的兔子不会是红色,否则他们的回答会相互矛盾。
36-
设回答了 "2" 的兔子为蓝色。
37-
此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
36+
设回答了 "2" 的兔子为蓝色。
37+
此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
3838
因此森林中兔子的最少数量是 5 只:3 只回答的和 2 只没有回答的。
3939
</pre>
4040

Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3466.Maximum%20Coin%20Collection/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3466. 最大硬币收藏量 🔒](https://leetcode.cn/problems/maximum-coin-collection)
10+
11+
[English Version](/solution/3400-3499/3466.Maximum%20Coin%20Collection/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>Mario 在双车道高速公路上行驶,每英里都有硬币。给定两个整数数组,<code>lane1</code> 和&nbsp;<code>lane2</code>,其中第&nbsp;<code>i</code>&nbsp;个下标的值表示他在车道上处于第&nbsp;<code>i</code>&nbsp;英里时获得或失去的硬币数量。</p>
18+
19+
<ul>
20+
<li>如果&nbsp;Mario 在车道 1 上处于&nbsp;<code>i</code> 英里处,并且&nbsp;<code>lane1[i] &gt; 0</code>,Mario 获得&nbsp;<code>lane1[i]</code> 硬币。</li>
21+
<li>如果 Mario 在车道 1 上处于&nbsp;<code>i</code>&nbsp;英里处,并且&nbsp;<code>lane1[i] &lt; 0</code>,Mario 支付通行费并失去&nbsp;<code>abs(lane1[i])</code>&nbsp;个硬币。</li>
22+
<li>规则同样对&nbsp;<code>lane2</code>&nbsp;适用。</li>
23+
</ul>
24+
25+
<p>Mario&nbsp;可以在任何地方进入高速公路,并在行驶 <strong>至少</strong> 一英里后随时退出。Mario 总是从 1 号车道进入高速公路,但 <strong>最多</strong> 可以换道 2 次。</p>
26+
27+
<p><strong>换道</strong>&nbsp;是指 Mario 从车道 1 换到车道 2,反之亦然。</p>
28+
29+
<p>返回 Mario 在进行&nbsp;<strong>最多 2 次换道</strong>&nbsp;&nbsp;<strong>最多</strong>&nbsp;可以获得的硬币数。</p>
30+
31+
<p><strong>注意:</strong>Mario&nbsp;可以在进入高速公路或退出高速公路之前立即切换车道。</p>
32+
33+
<p>&nbsp;</p>
34+
35+
<p><strong class="example">示例 1:</strong></p>
36+
37+
<div class="example-block">
38+
<p><span class="example-io"><b>输入:</b>lane1 = [1,-2,-10,3], lane2 = [-5,10,0,1]</span></p>
39+
40+
<p><span class="example-io"><b>输出:</b>14</span></p>
41+
42+
<p><strong>解释:</strong></p>
43+
44+
<ul>
45+
<li>Mario 在车道 1 上行驶了第 1 英里。</li>
46+
<li>接着,他切换到车道 2 并继续行驶 2 英里。</li>
47+
<li>最后 1 英里他切换回了车道 1。</li>
48+
</ul>
49+
50+
<p>Mario 收集了&nbsp;<code>1 +たす 10 +たす 0 +たす 3 = 14</code> 硬币。</p>
51+
</div>
52+
53+
<p><strong class="example">示例 2:</strong></p>
54+
55+
<div class="example-block">
56+
<p><span class="example-io"><b>输入:</b>lane1 = [1,-1,-1,-1], lane2 = [0,3,4,-5]</span></p>
57+
58+
<p><span class="example-io"><b>输出:</b>8</span></p>
59+
60+
<p><strong>解释:</strong></p>
61+
62+
<ul>
63+
<li>Mario 从 0 英里处进入车道 1 并行驶了 1 英里。</li>
64+
<li>接着,他切换到车道 2 并继续行驶了 2 英里。他在 3 英里处离开高速公路。</li>
65+
</ul>
66+
67+
<p>他总共收集了&nbsp;<code>1 + 3 + 4 = 8</code> 硬币。</p>
68+
</div>
69+
70+
<p><strong class="example">示例 3:</strong></p>
71+
72+
<div class="example-block">
73+
<p><span class="example-io"><b>输入:</b>lane1 = [-5,-4,-3], lane2 = [-1,2,3]</span></p>
74+
75+
<p><span class="example-io"><b>输出:</b>5</span></p>
76+
77+
<p><strong>解释:</strong></p>
78+
79+
<ul>
80+
<li>Mario 从 1 英里处进入并立即切换到车道 2。他全程保持在这根车道上。</li>
81+
</ul>
82+
83+
<p>他总共收集了&nbsp;<code>2 + 3 = 5</code>&nbsp;硬币。</p>
84+
</div>
85+
86+
<p><strong class="example">示例 4:</strong></p>
87+
88+
<div class="example-block">
89+
<p><span class="example-io"><b>输入:</b>lane1 = [-3,-3,-3], lane2 = [9,-2,4]</span></p>
90+
91+
<p><b>输出:</b>11</p>
92+
93+
<p><strong>解释:</strong></p>
94+
95+
<ul>
96+
<li>Mario 从高速公路的开头进入并立即切换到车道 2。他全程保持在这根车道上。</li>
97+
</ul>
98+
99+
<p>他总共获得了&nbsp;<code>9 + (-2) + 4 = 11</code> 硬币。</p>
100+
</div>
101+
102+
<p><strong class="example">示例 5:</strong></p>
103+
104+
<div class="example-block">
105+
<p><span class="example-io"><b>输入:</b>lane1 = [-10], lane2 = [-2]</span></p>
106+
107+
<p><span class="example-io"><b>输出:</b>-2</span></p>
108+
109+
<p><strong>解释:</strong></p>
110+
111+
<ul>
112+
<li>由于 Mario 必须在高速公路上行驶至少 1 英里,他只在车道 2 上行驶了 1 英里。</li>
113+
</ul>
114+
115+
<p>他总共获得了 -2 硬币。</p>
116+
</div>
117+
118+
<p>&nbsp;</p>
119+
120+
<p><strong>提示:</strong></p>
121+
122+
<ul>
123+
<li><code>1 &lt;= lane1.length == lane2.length &lt;= 10<sup>5</sup></code></li>
124+
<li><code>-10<sup>9</sup> &lt;= lane1[i], lane2[i] &lt;= 10<sup>9</sup></code></li>
125+
</ul>
126+
127+
<!-- description:end -->
128+
129+
## 解法
130+
131+
<!-- solution:start -->
132+
133+
### 方法一:记忆化搜索
134+
135+
我们设计一个函数 $\textit{dfs}(i, j, k),ドル表示 Mario 从第 $i$ 个位置开始,当前在第 $j$ 条车道上,还可以换道 $k$ 次的情况下,最多可以获得的硬币数。那么答案就是对于所有的 $i,ドル取 $\textit{dfs}(i, 0, 2)$ 的最大值。
136+
137+
函数 $\textit{dfs}(i, j, k)$ 的计算方式如下:
138+
139+
- 如果 $i \geq n,ドル表示已经走到了终点,返回 0;
140+
- 如果不变道,当前可以行驶 1 英里,然后驶出,或者继续行驶,取两者中的最大值,即 $\max(x, \textit{dfs}(i + 1, j, k) + x)$;
141+
- 如果可以变道,有两种选择,一种是行驶 1 英里,然后变道,另一种是直接变道,取这两种情况的最大值,即 $\max(\textit{dfs}(i + 1, j \oplus 1, k - 1) + x, \textit{dfs}(i, j \oplus 1, k - 1))$。
142+
- 其中 $x$ 表示当前位置的硬币数。
143+
144+
为了避免重复计算,我们使用记忆化搜索的方法,将已经计算过的结果保存下来。
145+
146+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 表示车道的长度。
147+
148+
<!-- tabs:start -->
149+
150+
#### Python3
151+
152+
```python
153+
class Solution:
154+
def maxCoins(self, lane1: List[int], lane2: List[int]) -> int:
155+
@cache
156+
def dfs(i: int, j: int, k: int) -> int:
157+
if i >= n:
158+
return 0
159+
x = lane1[i] if j == 0 else lane2[i]
160+
ans = max(x, dfs(i + 1, j, k) + x)
161+
if k > 0:
162+
ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x)
163+
ans = max(ans, dfs(i, j ^ 1, k - 1))
164+
return ans
165+
166+
n = len(lane1)
167+
ans = -inf
168+
for i in range(n):
169+
ans = max(ans, dfs(i, 0, 2))
170+
return ans
171+
```
172+
173+
#### Java
174+
175+
```java
176+
class Solution {
177+
private int n;
178+
private int[] lane1;
179+
private int[] lane2;
180+
private Long[][][] f;
181+
182+
public long maxCoins(int[] lane1, int[] lane2) {
183+
n = lane1.length;
184+
this.lane1 = lane1;
185+
this.lane2 = lane2;
186+
f = new Long[n][2][3];
187+
long ans = Long.MIN_VALUE;
188+
for (int i = 0; i < n; ++i) {
189+
ans = Math.max(ans, dfs(i, 0, 2));
190+
}
191+
return ans;
192+
}
193+
194+
private long dfs(int i, int j, int k) {
195+
if (i >= n) {
196+
return 0;
197+
}
198+
if (f[i][j][k] != null) {
199+
return f[i][j][k];
200+
}
201+
int x = j == 0 ? lane1[i] : lane2[i];
202+
long ans = Math.max(x, dfs(i + 1, j, k) + x);
203+
if (k > 0) {
204+
ans = Math.max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
205+
ans = Math.max(ans, dfs(i, j ^ 1, k - 1));
206+
}
207+
return f[i][j][k] = ans;
208+
}
209+
}
210+
```
211+
212+
#### C++
213+
214+
```cpp
215+
class Solution {
216+
public:
217+
long long maxCoins(vector<int>& lane1, vector<int>& lane2) {
218+
int n = lane1.size();
219+
long long ans = -1e18;
220+
vector<vector<vector<long long>>> f(n, vector<vector<long long>>(2, vector<long long>(3, -1e18)));
221+
auto dfs = [&](this auto&& dfs, int i, int j, int k) -> long long {
222+
if (i >= n) {
223+
return 0LL;
224+
}
225+
if (f[i][j][k] != -1e18) {
226+
return f[i][j][k];
227+
}
228+
int x = j == 0 ? lane1[i] : lane2[i];
229+
long long ans = max((long long) x, dfs(i + 1, j, k) + x);
230+
if (k > 0) {
231+
ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
232+
ans = max(ans, dfs(i, j ^ 1, k - 1));
233+
}
234+
return f[i][j][k] = ans;
235+
};
236+
for (int i = 0; i < n; ++i) {
237+
ans = max(ans, dfs(i, 0, 2));
238+
}
239+
return ans;
240+
}
241+
};
242+
```
243+
244+
#### Go
245+
246+
```go
247+
func maxCoins(lane1 []int, lane2 []int) int64 {
248+
n := len(lane1)
249+
f := make([][2][3]int64, n)
250+
for i := range f {
251+
for j := range f[i] {
252+
for k := range f[i][j] {
253+
f[i][j][k] = -1
254+
}
255+
}
256+
}
257+
var dfs func(int, int, int) int64
258+
dfs = func(i, j, k int) int64 {
259+
if i >= n {
260+
return 0
261+
}
262+
if f[i][j][k] != -1 {
263+
return f[i][j][k]
264+
}
265+
x := int64(lane1[i])
266+
if j == 1 {
267+
x = int64(lane2[i])
268+
}
269+
ans := max(x, dfs(i+1, j, k)+x)
270+
if k > 0 {
271+
ans = max(ans, dfs(i+1, j^1, k-1)+x)
272+
ans = max(ans, dfs(i, j^1, k-1))
273+
}
274+
f[i][j][k] = ans
275+
return ans
276+
}
277+
ans := int64(-1e18)
278+
for i := range lane1 {
279+
ans = max(ans, dfs(i, 0, 2))
280+
}
281+
return ans
282+
}
283+
```
284+
285+
#### TypeScript
286+
287+
```ts
288+
function maxCoins(lane1: number[], lane2: number[]): number {
289+
const n = lane1.length;
290+
const NEG_INF = -1e18;
291+
const f: number[][][] = Array.from({ length: n }, () =>
292+
Array.from({ length: 2 }, () => Array(3).fill(NEG_INF)),
293+
);
294+
const dfs = (dfs: Function, i: number, j: number, k: number): number => {
295+
if (i >= n) {
296+
return 0;
297+
}
298+
if (f[i][j][k] !== NEG_INF) {
299+
return f[i][j][k];
300+
}
301+
const x = j === 0 ? lane1[i] : lane2[i];
302+
let ans = Math.max(x, dfs(dfs, i + 1, j, k) + x);
303+
if (k > 0) {
304+
ans = Math.max(ans, dfs(dfs, i + 1, j ^ 1, k - 1) + x);
305+
ans = Math.max(ans, dfs(dfs, i, j ^ 1, k - 1));
306+
}
307+
f[i][j][k] = ans;
308+
return ans;
309+
};
310+
let ans = NEG_INF;
311+
for (let i = 0; i < n; ++i) {
312+
ans = Math.max(ans, dfs(dfs, i, 0, 2));
313+
}
314+
return ans;
315+
}
316+
```
317+
318+
<!-- tabs:end -->
319+
320+
<!-- solution:end -->
321+
322+
<!-- problem:end -->

0 commit comments

Comments
(0)

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