-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3466-MaximumCoinCollection.go
More file actions
186 lines (167 loc) · 6.82 KB
/
3466-MaximumCoinCollection.go
File metadata and controls
186 lines (167 loc) · 6.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package main
// 3466. Maximum Coin Collection
// 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.
// 1. If Mario is in lane 1 at mile i and lane1[i] > 0, Mario gains lane1[i] coins.
// 2. If Mario is in lane 1 at mile i and lane1[i] < 0, Mario pays a toll and loses abs(lane1[i]) coins.
// 3. 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 <= 10^5
// -10^9 <= lane1[i], lane2[i] <= 10^9
import "fmt"
func maxCoins(lane1 []int, lane2 []int) int64 {
n := len(lane1)
dp := make([][3]int64, n + 1)
res := int64(-1 << 63)// int64(math.MinInt64)
max := func (x, y int64) int64 { if x > y { return x; }; return y; }
for i := 1; i <= n; i++ {
for j := 0; j < 3; j++ {
if dp[i - 1][j] > 0 {
dp[i][j] = dp[i - 1][j]
}
if j > 0 {
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1])
}
if j == 1 {
dp[i][j] += int64(lane2[i-1])
} else {
dp[i][j] += int64(lane1[i-1])
}
res = max(res, dp[i][j])
}
}
return res
}
func maxCoins1(lane1 []int, lane2 []int) int64 {
n := len(lane1)
dp := make([][2][3]int64, n)
for i := range dp { // fill -1
for j := range dp[i] {
for k := range dp[i][j] {
dp[i][j][k] = -1
}
}
}
max := func (x, y int64) int64 { if x > y { return x; }; return y; }
var dfs func(i, j, k int) int64
dfs = func(i, j, k int) int64 {
if i >= n { return 0 }
if dp[i][j][k] != -1 { return dp[i][j][k] }
x := int64(lane1[i])
if j == 1 {
x = int64(lane2[i])
}
mx := max(x, dfs(i+1, j, k)+x)
if k > 0 {
mx = max(mx, max(dfs(i+1, j^1, k-1) + x, dfs(i, j^1, k-1)))
}
dp[i][j][k] = mx
return mx
}
res := int64(-1e18)
for i := range lane1 {
res = max(res, dfs(i, 0, 2))
}
return res
}
func maxCoins2(lane1 []int, lane2 []int) int64 {
var maxCoins, zeroSw, oneSw, twoSw int = -1e10, -1e10, -1e10, -1e10
for i := 0; i < len(lane1); i++ {
twoSw = max(twoSw + lane1[i], oneSw + lane1[i])
oneSw = max(oneSw + lane2[i], zeroSw + lane2[i], lane2[i])
zeroSw = max(lane1[i], zeroSw + lane1[i])
maxCoins = max(maxCoins, zeroSw, oneSw, twoSw)
}
return int64(maxCoins)
}
func main() {
// 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.
fmt.Println(maxCoins([]int{1,-2,-10,3}, []int{-5,10,0,1})) // 14
// 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.
fmt.Println(maxCoins([]int{1,-1,-1,-1}, []int{0,3,4,-5})) // 8
// 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.
fmt.Println(maxCoins([]int{-5,-4,-3}, []int{-1,2,3})) // 5
// 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.
fmt.Println(maxCoins([]int{-3,-3,-3}, []int{9,-2,4})) // 11
// 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.
fmt.Println(maxCoins([]int{-10}, []int{-2})) // -2
fmt.Println(maxCoins([]int{1,2,3,4,5,6,7,8,9}, []int{9,8,7,6,5,4,3,2,1})) // 65
fmt.Println(maxCoins1([]int{1,-2,-10,3}, []int{-5,10,0,1})) // 14
fmt.Println(maxCoins1([]int{1,-1,-1,-1}, []int{0,3,4,-5})) // 8
fmt.Println(maxCoins1([]int{-5,-4,-3}, []int{-1,2,3})) // 5
fmt.Println(maxCoins1([]int{-3,-3,-3}, []int{9,-2,4})) // 11
fmt.Println(maxCoins1([]int{-10}, []int{-2})) // -2
fmt.Println(maxCoins1([]int{1,2,3,4,5,6,7,8,9}, []int{9,8,7,6,5,4,3,2,1})) // 65
fmt.Println(maxCoins2([]int{1,-2,-10,3}, []int{-5,10,0,1})) // 14
fmt.Println(maxCoins2([]int{1,-1,-1,-1}, []int{0,3,4,-5})) // 8
fmt.Println(maxCoins2([]int{-5,-4,-3}, []int{-1,2,3})) // 5
fmt.Println(maxCoins2([]int{-3,-3,-3}, []int{9,-2,4})) // 11
fmt.Println(maxCoins2([]int{-10}, []int{-2})) // -2
fmt.Println(maxCoins2([]int{1,2,3,4,5,6,7,8,9}, []int{9,8,7,6,5,4,3,2,1})) // 65
}