diff --git a/solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md b/solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md
index c2b4f0a17c49b..e5477c5dd7084 100644
--- a/solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md
+++ b/solution/0700-0799/0768.Max Chunks To Make Sorted II/README.md
@@ -33,8 +33,8 @@ tags:
输入:arr = [5,4,3,2,1]
输出:1
解释:
-将数组分成2块或者更多块,都无法得到所需的结果。
-例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
+将数组分成2块或者更多块,都无法得到所需的结果。
+例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。
示例 2:
@@ -43,8 +43,8 @@ tags:
输入:arr = [2,1,3,4,4]
输出:4
解释:
-可以把它分成两块,例如 [2, 1], [3, 4, 4]。
-然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
+可以把它分成两块,例如 [2, 1], [3, 4, 4]。
+然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
diff --git a/solution/0700-0799/0779.K-th Symbol in Grammar/README.md b/solution/0700-0799/0779.K-th Symbol in Grammar/README.md
index 46f24db35cba2..44ae2ccd2bec3 100644
--- a/solution/0700-0799/0779.K-th Symbol in Grammar/README.md
+++ b/solution/0700-0799/0779.K-th Symbol in Grammar/README.md
@@ -40,8 +40,8 @@ tags:
输入: n = 2, k = 1
输出: 0
-解释:
-第一行: 0
+解释:
+第一行: 0
第二行: 01
diff --git a/solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md b/solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md
index a7784c0e35673..bce38a6ec809e 100644
--- a/solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md
+++ b/solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md
@@ -40,7 +40,7 @@ tags:
Input: n = 2, k = 1
Output: 0
-Explanation:
+Explanation:
row 1: 0
row 2: 01
@@ -50,7 +50,7 @@ row 2: 01
Input: n = 2, k = 2
Output: 1
-Explanation:
+Explanation:
row 1: 0
row 2: 01
diff --git a/solution/0700-0799/0781.Rabbits in Forest/README.md b/solution/0700-0799/0781.Rabbits in Forest/README.md
index 7ee81866b1060..a3cdab7dc9fe3 100644
--- a/solution/0700-0799/0781.Rabbits in Forest/README.md
+++ b/solution/0700-0799/0781.Rabbits in Forest/README.md
@@ -31,10 +31,10 @@ tags:
输入:answers = [1,1,2]
输出:5
解释:
-两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
+两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
之后回答了 "2" 的兔子不会是红色,否则他们的回答会相互矛盾。
-设回答了 "2" 的兔子为蓝色。
-此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
+设回答了 "2" 的兔子为蓝色。
+此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
因此森林中兔子的最少数量是 5 只:3 只回答的和 2 只没有回答的。
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/README.md b/solution/3400-3499/3466.Maximum Coin Collection/README.md
new file mode 100644
index 0000000000000..bff3146ac36a0
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/README.md
@@ -0,0 +1,322 @@
+---
+comments: true
+difficulty: 中等
+edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3466.Maximum%20Coin%20Collection/README.md
+---
+
+
+
+# [3466. 最大硬币收藏量 🔒](https://leetcode.cn/problems/maximum-coin-collection)
+
+[English Version](/solution/3400-3499/3466.Maximum%20Coin%20Collection/README_EN.md)
+
+## 题目描述
+
+
+
+Mario 在双车道高速公路上行驶,每英里都有硬币。给定两个整数数组,lane1
和 lane2
,其中第 i
个下标的值表示他在车道上处于第 i
英里时获得或失去的硬币数量。
+
+
+ - 如果 Mario 在车道 1 上处于
i
英里处,并且 lane1[i] > 0
,Mario 获得 lane1[i]
硬币。
+ - 如果 Mario 在车道 1 上处于
i
英里处,并且 lane1[i] < 0
,Mario 支付通行费并失去 abs(lane1[i])
个硬币。
+ - 规则同样对
lane2
适用。
+
+
+Mario 可以在任何地方进入高速公路,并在行驶 至少 一英里后随时退出。Mario 总是从 1 号车道进入高速公路,但 最多 可以换道 2 次。
+
+换道 是指 Mario 从车道 1 换到车道 2,反之亦然。
+
+返回 Mario 在进行 最多 2 次换道 后 最多 可以获得的硬币数。
+
+注意:Mario 可以在进入高速公路或退出高速公路之前立即切换车道。
+
+
+
+示例 1:
+
+
+
输入:lane1 = [1,-2,-10,3], lane2 = [-5,10,0,1]
+
+
输出:14
+
+
解释:
+
+
+ - Mario 在车道 1 上行驶了第 1 英里。
+ - 接着,他切换到车道 2 并继续行驶 2 英里。
+ - 最后 1 英里他切换回了车道 1。
+
+
+
Mario 收集了 1 + 10 + 0 + 3 = 14
硬币。
+
+
+示例 2:
+
+
+
输入:lane1 = [1,-1,-1,-1], lane2 = [0,3,4,-5]
+
+
输出:8
+
+
解释:
+
+
+ - Mario 从 0 英里处进入车道 1 并行驶了 1 英里。
+ - 接着,他切换到车道 2 并继续行驶了 2 英里。他在 3 英里处离开高速公路。
+
+
+
他总共收集了 1 + 3 + 4 = 8
硬币。
+
+
+示例 3:
+
+
+
输入:lane1 = [-5,-4,-3], lane2 = [-1,2,3]
+
+
输出:5
+
+
解释:
+
+
+ - Mario 从 1 英里处进入并立即切换到车道 2。他全程保持在这根车道上。
+
+
+
他总共收集了 2 + 3 = 5
硬币。
+
+
+示例 4:
+
+
+
输入:lane1 = [-3,-3,-3], lane2 = [9,-2,4]
+
+
输出:11
+
+
解释:
+
+
+ - Mario 从高速公路的开头进入并立即切换到车道 2。他全程保持在这根车道上。
+
+
+
他总共获得了 9 + (-2) + 4 = 11
硬币。
+
+
+示例 5:
+
+
+
输入:lane1 = [-10], lane2 = [-2]
+
+
输出:-2
+
+
解释:
+
+
+ - 由于 Mario 必须在高速公路上行驶至少 1 英里,他只在车道 2 上行驶了 1 英里。
+
+
+
他总共获得了 -2 硬币。
+
+
+
+
+提示:
+
+
+ 1 <= lane1.length == lane2.length <= 105
+ -109 <= lane1[i], lane2[i] <= 109
+
+
+
+
+## 解法
+
+
+
+### 方法一:记忆化搜索
+
+我们设计一个函数 $\textit{dfs}(i, j, k)$,表示 Mario 从第 $i$ 个位置开始,当前在第 $j$ 条车道上,还可以换道 $k$ 次的情况下,最多可以获得的硬币数。那么答案就是对于所有的 $i$,取 $\textit{dfs}(i, 0, 2)$ 的最大值。
+
+函数 $\textit{dfs}(i, j, k)$ 的计算方式如下:
+
+- 如果 $i \geq n$,表示已经走到了终点,返回 0;
+- 如果不变道,当前可以行驶 1 英里,然后驶出,或者继续行驶,取两者中的最大值,即 $\max(x, \textit{dfs}(i + 1, j, k) + x)$;
+- 如果可以变道,有两种选择,一种是行驶 1 英里,然后变道,另一种是直接变道,取这两种情况的最大值,即 $\max(\textit{dfs}(i + 1, j \oplus 1, k - 1) + x, \textit{dfs}(i, j \oplus 1, k - 1))$。
+- 其中 $x$ 表示当前位置的硬币数。
+
+为了避免重复计算,我们使用记忆化搜索的方法,将已经计算过的结果保存下来。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 表示车道的长度。
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def maxCoins(self, lane1: List[int], lane2: List[int]) -> int:
+ @cache
+ def dfs(i: int, j: int, k: int) -> int:
+ if i >= n:
+ return 0
+ x = lane1[i] if j == 0 else lane2[i]
+ ans = max(x, dfs(i + 1, j, k) + x)
+ if k > 0:
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x)
+ ans = max(ans, dfs(i, j ^ 1, k - 1))
+ return ans
+
+ n = len(lane1)
+ ans = -inf
+ for i in range(n):
+ ans = max(ans, dfs(i, 0, 2))
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ private int n;
+ private int[] lane1;
+ private int[] lane2;
+ private Long[][][] f;
+
+ public long maxCoins(int[] lane1, int[] lane2) {
+ n = lane1.length;
+ this.lane1 = lane1;
+ this.lane2 = lane2;
+ f = new Long[n][2][3];
+ long ans = Long.MIN_VALUE;
+ for (int i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+
+ private long dfs(int i, int j, int k) {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] != null) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long ans = Math.max(x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ long long maxCoins(vector& lane1, vector& lane2) {
+ int n = lane1.size();
+ long long ans = -1e18;
+ vector>> f(n, vector>(2, vector(3, -1e18)));
+ auto dfs = [&](this auto&& dfs, int i, int j, int k) -> long long {
+ if (i >= n) {
+ return 0LL;
+ }
+ if (f[i][j][k] != -1e18) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long long ans = max((long long) x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ };
+ for (int i = 0; i < n; ++i) {
+ ans = max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func maxCoins(lane1 []int, lane2 []int) int64 {
+ n := len(lane1)
+ f := make([][2][3]int64, n)
+ for i := range f {
+ for j := range f[i] {
+ for k := range f[i][j] {
+ f[i][j][k] = -1
+ }
+ }
+ }
+ var dfs func(int, int, int) int64
+ dfs = func(i, j, k int) int64 {
+ if i >= n {
+ return 0
+ }
+ if f[i][j][k] != -1 {
+ return f[i][j][k]
+ }
+ x := int64(lane1[i])
+ if j == 1 {
+ x = int64(lane2[i])
+ }
+ ans := max(x, dfs(i+1, j, k)+x)
+ if k > 0 {
+ ans = max(ans, dfs(i+1, j^1, k-1)+x)
+ ans = max(ans, dfs(i, j^1, k-1))
+ }
+ f[i][j][k] = ans
+ return ans
+ }
+ ans := int64(-1e18)
+ for i := range lane1 {
+ ans = max(ans, dfs(i, 0, 2))
+ }
+ return ans
+}
+```
+
+#### TypeScript
+
+```ts
+function maxCoins(lane1: number[], lane2: number[]): number {
+ const n = lane1.length;
+ const NEG_INF = -1e18;
+ const f: number[][][] = Array.from({ length: n }, () =>
+ Array.from({ length: 2 }, () => Array(3).fill(NEG_INF)),
+ );
+ const dfs = (dfs: Function, i: number, j: number, k: number): number => {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] !== NEG_INF) {
+ return f[i][j][k];
+ }
+ const x = j === 0 ? lane1[i] : lane2[i];
+ let ans = Math.max(x, dfs(dfs, i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(dfs, i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(dfs, i, j ^ 1, k - 1));
+ }
+ f[i][j][k] = ans;
+ return ans;
+ };
+ let ans = NEG_INF;
+ for (let i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(dfs, i, 0, 2));
+ }
+ return ans;
+}
+```
+
+
+
+
+
+
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/README_EN.md b/solution/3400-3499/3466.Maximum Coin Collection/README_EN.md
new file mode 100644
index 0000000000000..a2be4dd4b6241
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/README_EN.md
@@ -0,0 +1,320 @@
+---
+comments: true
+difficulty: Medium
+edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3466.Maximum%20Coin%20Collection/README_EN.md
+---
+
+
+
+# [3466. Maximum Coin Collection 🔒](https://leetcode.com/problems/maximum-coin-collection)
+
+[中文文档](/solution/3400-3499/3466.Maximum%20Coin%20Collection/README.md)
+
+## Description
+
+
+
+Mario drives on a two-lane freeway with coins every mile. You are given two integer arrays, lane1
and lane2
, where the value at the ith
index represents the number of coins he gains or loses in the ith
mile in that lane.
+
+
+ - If Mario is in lane 1 at mile
i
and lane1[i] > 0
, Mario gains lane1[i]
coins.
+ - If Mario is in lane 1 at mile
i
and lane1[i] < 0
, Mario pays a toll and loses abs(lane1[i])
coins.
+ - The same rules apply for
lane2
.
+
+
+Mario can enter the freeway anywhere and exit anytime after traveling at least one mile. Mario always enters the freeway on lane 1 but can switch lanes at most 2 times.
+
+A lane switch is when Mario goes from lane 1 to lane 2 or vice versa.
+
+Return the maximum number of coins Mario can earn after performing at most 2 lane switches.
+
+Note: Mario can switch lanes immediately upon entering or just before exiting the freeway.
+
+
+Example 1:
+
+
+
Input: lane1 = [1,-2,-10,3], lane2 = [-5,10,0,1]
+
+
Output: 14
+
+
Explanation:
+
+
+ - Mario drives the first mile on lane 1.
+ - He then changes to lane 2 and drives for two miles.
+ - He changes back to lane 1 for the last mile.
+
+
+
Mario collects 1 + 10 + 0 + 3 = 14
coins.
+
+
+Example 2:
+
+
+
Input: lane1 = [1,-1,-1,-1], lane2 = [0,3,4,-5]
+
+
Output: 8
+
+
Explanation:
+
+
+ - Mario starts at mile 0 in lane 1 and drives one mile.
+ - He then changes to lane 2 and drives for two more miles. He exits the freeway before mile 3.
+
+
+
He collects 1 + 3 + 4 = 8
coins.
+
+
+Example 3:
+
+
+
Input: lane1 = [-5,-4,-3], lane2 = [-1,2,3]
+
+
Output: 5
+
+
Explanation:
+
+
+ - Mario enters at mile 1 and immediately switches to lane 2. He stays here the entire way.
+
+
+
He collects a total of 2 + 3 = 5
coins.
+
+
+Example 4:
+
+
+
Input: lane1 = [-3,-3,-3], lane2 = [9,-2,4]
+
+
Output: 11
+
+
Explanation:
+
+
+ - Mario starts at the beginning of the freeway and immediately switches to lane 2. He stays here the whole way.
+
+
+
He collects a total of 9 + (-2) + 4 = 11
coins.
+
+
+Example 5:
+
+
+
Input: lane1 = [-10], lane2 = [-2]
+
+
Output: -2
+
+
Explanation:
+
+
+ - Since Mario must ride on the freeway for at least one mile, he rides just one mile in lane 2.
+
+
+
He collects a total of -2 coins.
+
+
+
+Constraints:
+
+
+ 1 <= lane1.length == lane2.length <= 105
+ -109 <= lane1[i], lane2[i] <= 109
+
+
+
+
+## Solutions
+
+
+
+### Solution 1: Memoized Search
+
+We design a function $\textit{dfs}(i, j, k)$, which represents the maximum number of coins Mario can collect starting from position $i$, currently on lane $j$, with $k$ lane changes remaining. The answer is the maximum value of $\textit{dfs}(i, 0, 2)$ for all $i$.
+
+The function $\textit{dfs}(i, j, k)$ is calculated as follows:
+
+- If $i \geq n$, it means Mario has reached the end, return 0;
+- If no lane change is made, Mario can drive 1 mile, then exit, or continue driving, taking the maximum of the two, i.e., $\max(x, \textit{dfs}(i + 1, j, k) + x)$;
+- If a lane change is possible, there are two choices: drive 1 mile and then change lanes, or change lanes directly, taking the maximum of these two cases, i.e., $\max(\textit{dfs}(i + 1, j \oplus 1, k - 1) + x, \textit{dfs}(i, j \oplus 1, k - 1))$.
+- Where $x$ represents the number of coins at the current position.
+
+To avoid repeated calculations, we use memoized search to store the results that have already been computed.
+
+Time complexity is $O(n)$, and space complexity is $O(n)$. Where $n$ represents the length of the lanes.
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def maxCoins(self, lane1: List[int], lane2: List[int]) -> int:
+ @cache
+ def dfs(i: int, j: int, k: int) -> int:
+ if i >= n:
+ return 0
+ x = lane1[i] if j == 0 else lane2[i]
+ ans = max(x, dfs(i + 1, j, k) + x)
+ if k > 0:
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x)
+ ans = max(ans, dfs(i, j ^ 1, k - 1))
+ return ans
+
+ n = len(lane1)
+ ans = -inf
+ for i in range(n):
+ ans = max(ans, dfs(i, 0, 2))
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ private int n;
+ private int[] lane1;
+ private int[] lane2;
+ private Long[][][] f;
+
+ public long maxCoins(int[] lane1, int[] lane2) {
+ n = lane1.length;
+ this.lane1 = lane1;
+ this.lane2 = lane2;
+ f = new Long[n][2][3];
+ long ans = Long.MIN_VALUE;
+ for (int i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+
+ private long dfs(int i, int j, int k) {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] != null) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long ans = Math.max(x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ long long maxCoins(vector& lane1, vector& lane2) {
+ int n = lane1.size();
+ long long ans = -1e18;
+ vector>> f(n, vector>(2, vector(3, -1e18)));
+ auto dfs = [&](this auto&& dfs, int i, int j, int k) -> long long {
+ if (i >= n) {
+ return 0LL;
+ }
+ if (f[i][j][k] != -1e18) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long long ans = max((long long) x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ };
+ for (int i = 0; i < n; ++i) {
+ ans = max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func maxCoins(lane1 []int, lane2 []int) int64 {
+ n := len(lane1)
+ f := make([][2][3]int64, n)
+ for i := range f {
+ for j := range f[i] {
+ for k := range f[i][j] {
+ f[i][j][k] = -1
+ }
+ }
+ }
+ var dfs func(int, int, int) int64
+ dfs = func(i, j, k int) int64 {
+ if i >= n {
+ return 0
+ }
+ if f[i][j][k] != -1 {
+ return f[i][j][k]
+ }
+ x := int64(lane1[i])
+ if j == 1 {
+ x = int64(lane2[i])
+ }
+ ans := max(x, dfs(i+1, j, k)+x)
+ if k > 0 {
+ ans = max(ans, dfs(i+1, j^1, k-1)+x)
+ ans = max(ans, dfs(i, j^1, k-1))
+ }
+ f[i][j][k] = ans
+ return ans
+ }
+ ans := int64(-1e18)
+ for i := range lane1 {
+ ans = max(ans, dfs(i, 0, 2))
+ }
+ return ans
+}
+```
+
+#### TypeScript
+
+```ts
+function maxCoins(lane1: number[], lane2: number[]): number {
+ const n = lane1.length;
+ const NEG_INF = -1e18;
+ const f: number[][][] = Array.from({ length: n }, () =>
+ Array.from({ length: 2 }, () => Array(3).fill(NEG_INF)),
+ );
+ const dfs = (dfs: Function, i: number, j: number, k: number): number => {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] !== NEG_INF) {
+ return f[i][j][k];
+ }
+ const x = j === 0 ? lane1[i] : lane2[i];
+ let ans = Math.max(x, dfs(dfs, i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(dfs, i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(dfs, i, j ^ 1, k - 1));
+ }
+ f[i][j][k] = ans;
+ return ans;
+ };
+ let ans = NEG_INF;
+ for (let i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(dfs, i, 0, 2));
+ }
+ return ans;
+}
+```
+
+
+
+
+
+
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/Solution.cpp b/solution/3400-3499/3466.Maximum Coin Collection/Solution.cpp
new file mode 100644
index 0000000000000..08ce9ddd71dab
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/Solution.cpp
@@ -0,0 +1,27 @@
+class Solution {
+public:
+ long long maxCoins(vector& lane1, vector& lane2) {
+ int n = lane1.size();
+ long long ans = -1e18;
+ vector>> f(n, vector>(2, vector(3, -1e18)));
+ auto dfs = [&](this auto&& dfs, int i, int j, int k) -> long long {
+ if (i >= n) {
+ return 0LL;
+ }
+ if (f[i][j][k] != -1e18) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long long ans = max((long long) x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ };
+ for (int i = 0; i < n; ++i) {
+ ans = max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+};
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/Solution.go b/solution/3400-3499/3466.Maximum Coin Collection/Solution.go
new file mode 100644
index 0000000000000..e2e779e02967c
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/Solution.go
@@ -0,0 +1,36 @@
+func maxCoins(lane1 []int, lane2 []int) int64 {
+ n := len(lane1)
+ f := make([][2][3]int64, n)
+ for i := range f {
+ for j := range f[i] {
+ for k := range f[i][j] {
+ f[i][j][k] = -1
+ }
+ }
+ }
+ var dfs func(int, int, int) int64
+ dfs = func(i, j, k int) int64 {
+ if i >= n {
+ return 0
+ }
+ if f[i][j][k] != -1 {
+ return f[i][j][k]
+ }
+ x := int64(lane1[i])
+ if j == 1 {
+ x = int64(lane2[i])
+ }
+ ans := max(x, dfs(i+1, j, k)+x)
+ if k > 0 {
+ ans = max(ans, dfs(i+1, j^1, k-1)+x)
+ ans = max(ans, dfs(i, j^1, k-1))
+ }
+ f[i][j][k] = ans
+ return ans
+ }
+ ans := int64(-1e18)
+ for i := range lane1 {
+ ans = max(ans, dfs(i, 0, 2))
+ }
+ return ans
+}
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/Solution.java b/solution/3400-3499/3466.Maximum Coin Collection/Solution.java
new file mode 100644
index 0000000000000..9cea8c6404fac
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/Solution.java
@@ -0,0 +1,34 @@
+class Solution {
+ private int n;
+ private int[] lane1;
+ private int[] lane2;
+ private Long[][][] f;
+
+ public long maxCoins(int[] lane1, int[] lane2) {
+ n = lane1.length;
+ this.lane1 = lane1;
+ this.lane2 = lane2;
+ f = new Long[n][2][3];
+ long ans = Long.MIN_VALUE;
+ for (int i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(i, 0, 2));
+ }
+ return ans;
+ }
+
+ private long dfs(int i, int j, int k) {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] != null) {
+ return f[i][j][k];
+ }
+ int x = j == 0 ? lane1[i] : lane2[i];
+ long ans = Math.max(x, dfs(i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(i, j ^ 1, k - 1));
+ }
+ return f[i][j][k] = ans;
+ }
+}
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/Solution.py b/solution/3400-3499/3466.Maximum Coin Collection/Solution.py
new file mode 100644
index 0000000000000..9e7feed751679
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/Solution.py
@@ -0,0 +1,18 @@
+class Solution:
+ def maxCoins(self, lane1: List[int], lane2: List[int]) -> int:
+ @cache
+ def dfs(i: int, j: int, k: int) -> int:
+ if i >= n:
+ return 0
+ x = lane1[i] if j == 0 else lane2[i]
+ ans = max(x, dfs(i + 1, j, k) + x)
+ if k > 0:
+ ans = max(ans, dfs(i + 1, j ^ 1, k - 1) + x)
+ ans = max(ans, dfs(i, j ^ 1, k - 1))
+ return ans
+
+ n = len(lane1)
+ ans = -inf
+ for i in range(n):
+ ans = max(ans, dfs(i, 0, 2))
+ return ans
diff --git a/solution/3400-3499/3466.Maximum Coin Collection/Solution.ts b/solution/3400-3499/3466.Maximum Coin Collection/Solution.ts
new file mode 100644
index 0000000000000..4cf63bf5b4c96
--- /dev/null
+++ b/solution/3400-3499/3466.Maximum Coin Collection/Solution.ts
@@ -0,0 +1,28 @@
+function maxCoins(lane1: number[], lane2: number[]): number {
+ const n = lane1.length;
+ const NEG_INF = -1e18;
+ const f: number[][][] = Array.from({ length: n }, () =>
+ Array.from({ length: 2 }, () => Array(3).fill(NEG_INF)),
+ );
+ const dfs = (dfs: Function, i: number, j: number, k: number): number => {
+ if (i >= n) {
+ return 0;
+ }
+ if (f[i][j][k] !== NEG_INF) {
+ return f[i][j][k];
+ }
+ const x = j === 0 ? lane1[i] : lane2[i];
+ let ans = Math.max(x, dfs(dfs, i + 1, j, k) + x);
+ if (k > 0) {
+ ans = Math.max(ans, dfs(dfs, i + 1, j ^ 1, k - 1) + x);
+ ans = Math.max(ans, dfs(dfs, i, j ^ 1, k - 1));
+ }
+ f[i][j][k] = ans;
+ return ans;
+ };
+ let ans = NEG_INF;
+ for (let i = 0; i < n; ++i) {
+ ans = Math.max(ans, dfs(dfs, i, 0, 2));
+ }
+ return ans;
+}
diff --git a/solution/README.md b/solution/README.md
index 90e443df42bbd..870db42826621 100644
--- a/solution/README.md
+++ b/solution/README.md
@@ -3476,6 +3476,7 @@
| 3463 | [判断操作后字符串中的数字是否相等 II](/solution/3400-3499/3463.Check%20If%20Digits%20Are%20Equal%20in%20String%20After%20Operations%20II/README.md) | | 困难 | 第 438 场周赛 |
| 3464 | [正方形上的点之间的最大距离](/solution/3400-3499/3464.Maximize%20the%20Distance%20Between%20Points%20on%20a%20Square/README.md) | | 困难 | 第 438 场周赛 |
| 3465 | [Find Products with Valid Serial Numbers](/solution/3400-3499/3465.Find%20Products%20with%20Valid%20Serial%20Numbers/README.md) | | 简单 | |
+| 3466 | [最大硬币收藏量](/solution/3400-3499/3466.Maximum%20Coin%20Collection/README.md) | | 中等 | 🔒 |
## 版权
diff --git a/solution/README_EN.md b/solution/README_EN.md
index 8fb2a0ec5d0d0..10774975fd677 100644
--- a/solution/README_EN.md
+++ b/solution/README_EN.md
@@ -3474,6 +3474,7 @@ Press Control + F(or Command + F on
| 3463 | [Check If Digits Are Equal in String After Operations II](/solution/3400-3499/3463.Check%20If%20Digits%20Are%20Equal%20in%20String%20After%20Operations%20II/README_EN.md) | | Hard | Weekly Contest 438 |
| 3464 | [Maximize the Distance Between Points on a Square](/solution/3400-3499/3464.Maximize%20the%20Distance%20Between%20Points%20on%20a%20Square/README_EN.md) | | Hard | Weekly Contest 438 |
| 3465 | [Find Products with Valid Serial Numbers](/solution/3400-3499/3465.Find%20Products%20with%20Valid%20Serial%20Numbers/README_EN.md) | | Easy | |
+| 3466 | [Maximum Coin Collection](/solution/3400-3499/3466.Maximum%20Coin%20Collection/README_EN.md) | | Medium | 🔒 |
## Copyright