Skip to content

Commit 6fe2fcf

Browse files
authored
feat: add solutions to lc problem: No.0741 (doocs#2723)
No.0741.Cherry Pickup
1 parent 739df2d commit 6fe2fcf

File tree

8 files changed

+257
-139
lines changed

8 files changed

+257
-139
lines changed

solution/0700-0799/0741.Cherry Pickup/README.md

+89-48
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,28 @@
6262

6363
### 方法一:动态规划
6464

65-
线性 DP。题目中,玩家从 `(0, 0)``(N-1, N-1)` 后又重新返回到起始点 `(0, 0)`,我们可以视为玩家两次从 `(0, 0)` 出发到 `(N-1, N-1)`
65+
根据题目描述,玩家从 $(0, 0)$ 出发,到达 $(n-1, n-1)$ 后,又重新返回到起始点 $(0, 0)$,我们可以视为玩家两次从 $(0, 0)$ 出发,到达 $(n-1, n-1)$
6666

67-
定义 `dp[k][i1][i2]` 表示两次路径同时走了 k 步,并且第一次走到 `(i1, k-i1)`,第二次走到 `(i2, k-i2)` 的所有路径中,可获得的樱桃数量的最大值
67+
因此,我们定义 $f[k][i_1][i_2]$ 表示两次都走了 $k$ 步,分别到达 $(i_1, k-i_1)$ 和 $(i_2, k-i_2)$ 时,能够摘到的最多樱桃数。初始时 $f[0][0][0] = grid[0][0]$。其余 $f[k][i_1][i_2]$ 的初始值为负无穷。答案为 $\max(0, f[2n-2][n-1][n-1])$
6868

69-
类似题型:方格取数、传纸条。
69+
我们可以根据题目描述,得到状态转移方程:
70+
71+
$$
72+
f[k][i_1][i_2] = \max(f[k-1][x_1][x_2] + t, f[k][i_1][i_2])
73+
$$
74+
75+
其中 $t$ 表示 $(i_1, k-i_1)$ 和 $(i_2, k-i_2)$ 位置上的樱桃数,而 $x_1, x_2$ 分别表示 $(i_1, k-i_1)$ 和 $(i_2, k-i_2)$ 的前一步位置。
76+
77+
时间复杂度 $O(n^3)$,空间复杂度 $O(n^3)$。其中 $n$ 表示网格的边长。
7078

7179
<!-- tabs:start -->
7280

7381
```python
7482
class Solution:
7583
def cherryPickup(self, grid: List[List[int]]) -> int:
7684
n = len(grid)
77-
dp = [[[-inf] * n for _ in range(n)] for _ in range((n << 1) - 1)]
78-
dp[0][0][0] = grid[0][0]
85+
f = [[[-inf] * n for _ in range(n)] for _ in range((n << 1) - 1)]
86+
f[0][0][0] = grid[0][0]
7987
for k in range(1, (n << 1) - 1):
8088
for i1 in range(n):
8189
for i2 in range(n):
@@ -93,23 +101,21 @@ class Solution:
93101
for x1 in range(i1 - 1, i1 + 1):
94102
for x2 in range(i2 - 1, i2 + 1):
95103
if x1 >= 0 and x2 >= 0:
96-
dp[k][i1][i2] = max(
97-
dp[k][i1][i2], dp[k - 1][x1][x2] + t
98-
)
99-
return max(0, dp[-1][-1][-1])
104+
f[k][i1][i2] = max(f[k][i1][i2], f[k - 1][x1][x2] + t)
105+
return max(0, f[-1][-1][-1])
100106
```
101107

102108
```java
103109
class Solution {
104110
public int cherryPickup(int[][] grid) {
105111
int n = grid.length;
106-
int[][][] dp = new int[n * 2][n][n];
107-
dp[0][0][0] = grid[0][0];
112+
int[][][] f = new int[n * 2][n][n];
113+
f[0][0][0] = grid[0][0];
108114
for (int k = 1; k < n * 2 - 1; ++k) {
109115
for (int i1 = 0; i1 < n; ++i1) {
110116
for (int i2 = 0; i2 < n; ++i2) {
111117
int j1 = k - i1, j2 = k - i2;
112-
dp[k][i1][i2] = Integer.MIN_VALUE;
118+
f[k][i1][i2] = Integer.MIN_VALUE;
113119
if (j1 < 0 || j1 >= n || j2 < 0 || j2 >= n || grid[i1][j1] == -1
114120
|| grid[i2][j2] == -1) {
115121
continue;
@@ -121,14 +127,14 @@ class Solution {
121127
for (int x1 = i1 - 1; x1 <= i1; ++x1) {
122128
for (int x2 = i2 - 1; x2 <= i2; ++x2) {
123129
if (x1 >= 0 && x2 >= 0) {
124-
dp[k][i1][i2] = Math.max(dp[k][i1][i2], dp[k - 1][x1][x2] + t);
130+
f[k][i1][i2] = Math.max(f[k][i1][i2], f[k - 1][x1][x2] + t);
125131
}
126132
}
127133
}
128134
}
129135
}
130136
}
131-
return Math.max(0, dp[n * 2 - 2][n - 1][n - 1]);
137+
return Math.max(0, f[n * 2 - 2][n - 1][n - 1]);
132138
}
133139
}
134140
```
@@ -138,42 +144,49 @@ class Solution {
138144
public:
139145
int cherryPickup(vector<vector<int>>& grid) {
140146
int n = grid.size();
141-
vector<vector<vector<int>>> dp(n << 1, vector<vector<int>>(n, vector<int>(n, -1e9)));
142-
dp[0][0][0] = grid[0][0];
147+
vector<vector<vector<int>>> f(n << 1, vector<vector<int>>(n, vector<int>(n, -1e9)));
148+
f[0][0][0] = grid[0][0];
143149
for (int k = 1; k < n * 2 - 1; ++k) {
144150
for (int i1 = 0; i1 < n; ++i1) {
145151
for (int i2 = 0; i2 < n; ++i2) {
146152
int j1 = k - i1, j2 = k - i2;
147-
if (j1 < 0 || j1 >= n || j2 < 0 || j2 >= n || grid[i1][j1] == -1 || grid[i2][j2] == -1) continue;
153+
if (j1 < 0 || j1 >= n || j2 < 0 || j2 >= n || grid[i1][j1] == -1 || grid[i2][j2] == -1) {
154+
continue;
155+
}
148156
int t = grid[i1][j1];
149-
if (i1 != i2) t += grid[i2][j2];
150-
for (int x1 = i1 - 1; x1 <= i1; ++x1)
151-
for (int x2 = i2 - 1; x2 <= i2; ++x2)
152-
if (x1 >= 0 && x2 >= 0)
153-
dp[k][i1][i2] = max(dp[k][i1][i2], dp[k - 1][x1][x2] + t);
157+
if (i1 != i2) {
158+
t += grid[i2][j2];
159+
}
160+
for (int x1 = i1 - 1; x1 <= i1; ++x1) {
161+
for (int x2 = i2 - 1; x2 <= i2; ++x2) {
162+
if (x1 >= 0 && x2 >= 0) {
163+
f[k][i1][i2] = max(f[k][i1][i2], f[k - 1][x1][x2] + t);
164+
}
165+
}
166+
}
154167
}
155168
}
156169
}
157-
return max(0, dp[n * 2 - 2][n - 1][n - 1]);
170+
return max(0, f[n * 2 - 2][n - 1][n - 1]);
158171
}
159172
};
160173
```
161174
162175
```go
163176
func cherryPickup(grid [][]int) int {
164177
n := len(grid)
165-
dp := make([][][]int, (n<<1)-1)
166-
for i := range dp {
167-
dp[i] = make([][]int, n)
168-
for j := range dp[i] {
169-
dp[i][j] = make([]int, n)
178+
f := make([][][]int, (n<<1)-1)
179+
for i := range f {
180+
f[i] = make([][]int, n)
181+
for j := range f[i] {
182+
f[i][j] = make([]int, n)
170183
}
171184
}
172-
dp[0][0][0] = grid[0][0]
185+
f[0][0][0] = grid[0][0]
173186
for k := 1; k < (n<<1)-1; k++ {
174187
for i1 := 0; i1 < n; i1++ {
175188
for i2 := 0; i2 < n; i2++ {
176-
dp[k][i1][i2] = int(-1e9)
189+
f[k][i1][i2] = int(-1e9)
177190
j1, j2 := k-i1, k-i2
178191
if j1 < 0 || j1 >= n || j2 < 0 || j2 >= n || grid[i1][j1] == -1 || grid[i2][j2] == -1 {
179192
continue
@@ -185,14 +198,50 @@ func cherryPickup(grid [][]int) int {
185198
for x1 := i1 - 1; x1 <= i1; x1++ {
186199
for x2 := i2 - 1; x2 <= i2; x2++ {
187200
if x1 >= 0 && x2 >= 0 {
188-
dp[k][i1][i2] = max(dp[k][i1][i2], dp[k-1][x1][x2]+t)
201+
f[k][i1][i2] = max(f[k][i1][i2], f[k-1][x1][x2]+t)
189202
}
190203
}
191204
}
192205
}
193206
}
194207
}
195-
return max(0, dp[n*2-2][n-1][n-1])
208+
return max(0, f[n*2-2][n-1][n-1])
209+
}
210+
```
211+
212+
```ts
213+
function cherryPickup(grid: number[][]): number {
214+
const n: number = grid.length;
215+
const f: number[][][] = Array.from({ length: n * 2 - 1 }, () =>
216+
Array.from({ length: n }, () => Array.from({ length: n }, () => -Infinity)),
217+
);
218+
f[0][0][0] = grid[0][0];
219+
for (let k = 1; k < n * 2 - 1; ++k) {
220+
for (let i1 = 0; i1 < n; ++i1) {
221+
for (let i2 = 0; i2 < n; ++i2) {
222+
const [j1, j2]: [number, number] = [k - i1, k - i2];
223+
if (
224+
j1 < 0 ||
225+
j1 >= n ||
226+
j2 < 0 ||
227+
j2 >= n ||
228+
grid[i1][j1] == -1 ||
229+
grid[i2][j2] == -1
230+
) {
231+
continue;
232+
}
233+
const t: number = grid[i1][j1] + (i1 != i2 ? grid[i2][j2] : 0);
234+
for (let x1 = i1 - 1; x1 <= i1; ++x1) {
235+
for (let x2 = i2 - 1; x2 <= i2; ++x2) {
236+
if (x1 >= 0 && x2 >= 0) {
237+
f[k][i1][i2] = Math.max(f[k][i1][i2], f[k - 1][x1][x2] + t);
238+
}
239+
}
240+
}
241+
}
242+
}
243+
}
244+
return Math.max(0, f[n * 2 - 2][n - 1][n - 1]);
196245
}
197246
```
198247

@@ -203,19 +252,14 @@ func cherryPickup(grid [][]int) int {
203252
*/
204253
var cherryPickup = function (grid) {
205254
const n = grid.length;
206-
let dp = new Array(n * 2 - 1);
207-
for (let k = 0; k < dp.length; ++k) {
208-
dp[k] = new Array(n);
209-
for (let i = 0; i < n; ++i) {
210-
dp[k][i] = new Array(n).fill(-1e9);
211-
}
212-
}
213-
dp[0][0][0] = grid[0][0];
255+
const f = Array.from({ length: n * 2 - 1 }, () =>
256+
Array.from({ length: n }, () => Array.from({ length: n }, () => -Infinity)),
257+
);
258+
f[0][0][0] = grid[0][0];
214259
for (let k = 1; k < n * 2 - 1; ++k) {
215260
for (let i1 = 0; i1 < n; ++i1) {
216261
for (let i2 = 0; i2 < n; ++i2) {
217-
const j1 = k - i1,
218-
j2 = k - i2;
262+
const [j1, j2] = [k - i1, k - i2];
219263
if (
220264
j1 < 0 ||
221265
j1 >= n ||
@@ -226,21 +270,18 @@ var cherryPickup = function (grid) {
226270
) {
227271
continue;
228272
}
229-
let t = grid[i1][j1];
230-
if (i1 != i2) {
231-
t += grid[i2][j2];
232-
}
273+
const t = grid[i1][j1] + (i1 != i2 ? grid[i2][j2] : 0);
233274
for (let x1 = i1 - 1; x1 <= i1; ++x1) {
234275
for (let x2 = i2 - 1; x2 <= i2; ++x2) {
235276
if (x1 >= 0 && x2 >= 0) {
236-
dp[k][i1][i2] = Math.max(dp[k][i1][i2], dp[k - 1][x1][x2] + t);
277+
f[k][i1][i2] = Math.max(f[k][i1][i2], f[k - 1][x1][x2] + t);
237278
}
238279
}
239280
}
240281
}
241282
}
242283
}
243-
return Math.max(0, dp[n * 2 - 2][n - 1][n - 1]);
284+
return Math.max(0, f[n * 2 - 2][n - 1][n - 1]);
244285
};
245286
```
246287

0 commit comments

Comments
 (0)