From 11ca9ef5f0eccb05bd5869c3e03fd46fbd8d92ff Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 25 Feb 2025 11:41:15 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3466 No.3466.Maximum Coin Collection --- .../README.md | 8 +- .../0779.K-th Symbol in Grammar/README.md | 4 +- .../0779.K-th Symbol in Grammar/README_EN.md | 4 +- .../0781.Rabbits in Forest/README.md | 6 +- .../3466.Maximum Coin Collection/README.md | 322 ++++++++++++++++++ .../3466.Maximum Coin Collection/README_EN.md | 320 +++++++++++++++++ .../3466.Maximum Coin Collection/Solution.cpp | 27 ++ .../3466.Maximum Coin Collection/Solution.go | 36 ++ .../Solution.java | 34 ++ .../3466.Maximum Coin Collection/Solution.py | 18 + .../3466.Maximum Coin Collection/Solution.ts | 28 ++ solution/README.md | 1 + solution/README_EN.md | 1 + 13 files changed, 798 insertions(+), 11 deletions(-) create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/README.md create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/README_EN.md create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/Solution.cpp create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/Solution.go create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/Solution.java create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/Solution.py create mode 100644 solution/3400-3499/3466.Maximum Coin Collection/Solution.ts 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 可以在任何地方进入高速公路,并在行驶 至少 一英里后随时退出。Mario 总是从 1 号车道进入高速公路,但 最多 可以换道 2 次。

+ +

换道 是指 Mario 从车道 1 换到车道 2,反之亦然。

+ +

返回 Mario 在进行 最多 2 次换道 后 最多 可以获得的硬币数。

+ +

注意:Mario 可以在进入高速公路或退出高速公路之前立即切换车道。

+ +

 

+ +

示例 1:

+ +
+

输入:lane1 = [1,-2,-10,3], lane2 = [-5,10,0,1]

+ +

输出:14

+ +

解释:

+ + + +

Mario 收集了 1 + 10 + 0 + 3 = 14 硬币。

+
+ +

示例 2:

+ +
+

输入:lane1 = [1,-1,-1,-1], lane2 = [0,3,4,-5]

+ +

输出:8

+ +

解释:

+ + + +

他总共收集了 1 + 3 + 4 = 8 硬币。

+
+ +

示例 3:

+ +
+

输入:lane1 = [-5,-4,-3], lane2 = [-1,2,3]

+ +

输出:5

+ +

解释:

+ + + +

他总共收集了 2 + 3 = 5 硬币。

+
+ +

示例 4:

+ +
+

输入:lane1 = [-3,-3,-3], lane2 = [9,-2,4]

+ +

输出:11

+ +

解释:

+ + + +

他总共获得了 9 + (-2) + 4 = 11 硬币。

+
+ +

示例 5:

+ +
+

输入:lane1 = [-10], lane2 = [-2]

+ +

输出:-2

+ +

解释:

+ + + +

他总共获得了 -2 硬币。

+
+ +

 

+ +

提示:

+ + + + + +## 解法 + + + +### 方法一:记忆化搜索 + +我们设计一个函数 $\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