Skip to content

Commit 9ef585e

Browse files
authored
feat: add solutions to lc problem: No.3363 (doocs#4625)
No.3363.Find the Maximum Number of Fruits Collected
1 parent d469b75 commit 9ef585e

File tree

8 files changed

+635
-8
lines changed

8 files changed

+635
-8
lines changed

solution/3300-3399/3363.Find the Maximum Number of Fruits Collected/README.md

Lines changed: 223 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,32 +96,251 @@ tags:
9696

9797
<!-- solution:start -->
9898

99-
### 方法一
99+
### 方法一:动态规划
100+
101+
根据题目描述,从 $(0, 0)$ 出发的小朋友要想在 $n - 1$ 步后到达 $(n - 1, n - 1)$,那么他只能走主对角线上的房间 $(i, i)$,即 $i = 0, 1, \ldots, n - 1$。而从 $(0, n - 1)$ 出发的小朋友只能走主对角线以上的房间,而从 $(n - 1, 0)$ 出发的小朋友只能走主对角线以下的房间。这意味着三个小朋友除了在 $(n - 1, n - 1)$ 到达终点外,其他房间都不会有多个小朋友重复进入。
102+
103+
我们可以用动态规划的方式,计算从 $(0, n - 1)$ 和 $(n - 1, 0)$ 出发的小朋友达到 $(i, j)$ 时,能收集到的水果数。定义 $f[i][j]$ 表示小朋友到达 $(i, j)$ 时能收集到的水果数。
104+
105+
对于从 $(0, n - 1)$ 出发的小朋友,状态转移方程为:
106+
107+
$$
108+
f[i][j] = \max(f[i - 1][j], f[i - 1][j - 1], f[i - 1][j + 1]) + \text{fruits}[i][j]
109+
$$
110+
111+
注意,只有当 $j + 1 < n$ 时,$f[i - 1][j + 1]$ 才是有效的。
112+
113+
对于从 $(n - 1, 0)$ 出发的小朋友,状态转移方程为:
114+
115+
$$
116+
f[i][j] = \max(f[i][j - 1], f[i - 1][j - 1], f[i + 1][j - 1]) + \text{fruits}[i][j]
117+
$$
118+
119+
同样,只有当 $i + 1 < n$ 时,$f[i + 1][j - 1]$ 才是有效的。
120+
121+
最后,答案为 $\sum_{i=0}^{n-1} \text{fruits}[i][i] + f[n-2][n-1] + f[n-1][n-2]$,即主对角线上的水果数加上两个小朋友到达 $(n - 2, n - 1)$ 和 $(n - 1, n - 2)$ 时能收集到的水果数。
122+
123+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为房间的边长。
100124

101125
<!-- tabs:start -->
102126

103127
#### Python3
104128

105129
```python
106-
130+
class Solution:
131+
def maxCollectedFruits(self, fruits: List[List[int]]) -> int:
132+
n = len(fruits)
133+
f = [[-inf] * n for _ in range(n)]
134+
f[0][n - 1] = fruits[0][n - 1]
135+
for i in range(1, n):
136+
for j in range(i + 1, n):
137+
f[i][j] = max(f[i - 1][j], f[i - 1][j - 1]) + fruits[i][j]
138+
if j + 1 < n:
139+
f[i][j] = max(f[i][j], f[i - 1][j + 1] + fruits[i][j])
140+
f[n - 1][0] = fruits[n - 1][0]
141+
for j in range(1, n):
142+
for i in range(j + 1, n):
143+
f[i][j] = max(f[i][j - 1], f[i - 1][j - 1]) + fruits[i][j]
144+
if i + 1 < n:
145+
f[i][j] = max(f[i][j], f[i + 1][j - 1] + fruits[i][j])
146+
return sum(fruits[i][i] for i in range(n)) + f[n - 2][n - 1] + f[n - 1][n - 2]
107147
```
108148

109149
#### Java
110150

111151
```java
112-
152+
class Solution {
153+
public int maxCollectedFruits(int[][] fruits) {
154+
int n = fruits.length;
155+
final int inf = 1 << 29;
156+
int[][] f = new int[n][n];
157+
for (var row : f) {
158+
Arrays.fill(row, -inf);
159+
}
160+
f[0][n - 1] = fruits[0][n - 1];
161+
for (int i = 1; i < n; i++) {
162+
for (int j = i + 1; j < n; j++) {
163+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - 1]) + fruits[i][j];
164+
if (j + 1 < n) {
165+
f[i][j] = Math.max(f[i][j], f[i - 1][j + 1] + fruits[i][j]);
166+
}
167+
}
168+
}
169+
f[n - 1][0] = fruits[n - 1][0];
170+
for (int j = 1; j < n; j++) {
171+
for (int i = j + 1; i < n; i++) {
172+
f[i][j] = Math.max(f[i][j - 1], f[i - 1][j - 1]) + fruits[i][j];
173+
if (i + 1 < n) {
174+
f[i][j] = Math.max(f[i][j], f[i + 1][j - 1] + fruits[i][j]);
175+
}
176+
}
177+
}
178+
int ans = f[n - 2][n - 1] + f[n - 1][n - 2];
179+
for (int i = 0; i < n; i++) {
180+
ans += fruits[i][i];
181+
}
182+
return ans;
183+
}
184+
}
113185
```
114186

115187
#### C++
116188

117189
```cpp
118-
190+
class Solution {
191+
public:
192+
int maxCollectedFruits(vector<vector<int>>& fruits) {
193+
int n = fruits.size();
194+
const int inf = 1 << 29;
195+
vector<vector<int>> f(n, vector<int>(n, -inf));
196+
197+
f[0][n - 1] = fruits[0][n - 1];
198+
for (int i = 1; i < n; i++) {
199+
for (int j = i + 1; j < n; j++) {
200+
f[i][j] = max(f[i - 1][j], f[i - 1][j - 1]) + fruits[i][j];
201+
if (j + 1 < n) {
202+
f[i][j] = max(f[i][j], f[i - 1][j + 1] + fruits[i][j]);
203+
}
204+
}
205+
}
206+
207+
f[n - 1][0] = fruits[n - 1][0];
208+
for (int j = 1; j < n; j++) {
209+
for (int i = j + 1; i < n; i++) {
210+
f[i][j] = max(f[i][j - 1], f[i - 1][j - 1]) + fruits[i][j];
211+
if (i + 1 < n) {
212+
f[i][j] = max(f[i][j], f[i + 1][j - 1] + fruits[i][j]);
213+
}
214+
}
215+
}
216+
217+
int ans = f[n - 2][n - 1] + f[n - 1][n - 2];
218+
for (int i = 0; i < n; i++) {
219+
ans += fruits[i][i];
220+
}
221+
222+
return ans;
223+
}
224+
};
119225
```
120226

121227
#### Go
122228

123229
```go
230+
func maxCollectedFruits(fruits [][]int) int {
231+
n := len(fruits)
232+
const inf = 1 << 29
233+
f := make([][]int, n)
234+
for i := range f {
235+
f[i] = make([]int, n)
236+
for j := range f[i] {
237+
f[i][j] = -inf
238+
}
239+
}
240+
241+
f[0][n-1] = fruits[0][n-1]
242+
for i := 1; i < n; i++ {
243+
for j := i + 1; j < n; j++ {
244+
f[i][j] = max(f[i-1][j], f[i-1][j-1]) + fruits[i][j]
245+
if j+1 < n {
246+
f[i][j] = max(f[i][j], f[i-1][j+1]+fruits[i][j])
247+
}
248+
}
249+
}
250+
251+
f[n-1][0] = fruits[n-1][0]
252+
for j := 1; j < n; j++ {
253+
for i := j + 1; i < n; i++ {
254+
f[i][j] = max(f[i][j-1], f[i-1][j-1]) + fruits[i][j]
255+
if i+1 < n {
256+
f[i][j] = max(f[i][j], f[i+1][j-1]+fruits[i][j])
257+
}
258+
}
259+
}
260+
261+
ans := f[n-2][n-1] + f[n-1][n-2]
262+
for i := 0; i < n; i++ {
263+
ans += fruits[i][i]
264+
}
265+
266+
return ans
267+
}
268+
```
269+
270+
#### TypeScript
271+
272+
```ts
273+
function maxCollectedFruits(fruits: number[][]): number {
274+
const n = fruits.length;
275+
const inf = 1 << 29;
276+
const f: number[][] = Array.from({ length: n }, () => Array(n).fill(-inf));
277+
278+
f[0][n - 1] = fruits[0][n - 1];
279+
for (let i = 1; i < n; i++) {
280+
for (let j = i + 1; j < n; j++) {
281+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - 1]) + fruits[i][j];
282+
if (j + 1 < n) {
283+
f[i][j] = Math.max(f[i][j], f[i - 1][j + 1] + fruits[i][j]);
284+
}
285+
}
286+
}
287+
288+
f[n - 1][0] = fruits[n - 1][0];
289+
for (let j = 1; j < n; j++) {
290+
for (let i = j + 1; i < n; i++) {
291+
f[i][j] = Math.max(f[i][j - 1], f[i - 1][j - 1]) + fruits[i][j];
292+
if (i + 1 < n) {
293+
f[i][j] = Math.max(f[i][j], f[i + 1][j - 1] + fruits[i][j]);
294+
}
295+
}
296+
}
297+
298+
let ans = f[n - 2][n - 1] + f[n - 1][n - 2];
299+
for (let i = 0; i < n; i++) {
300+
ans += fruits[i][i];
301+
}
302+
303+
return ans;
304+
}
305+
```
124306

307+
#### Rust
308+
309+
```rust
310+
impl Solution {
311+
pub fn max_collected_fruits(fruits: Vec<Vec<i32>>) -> i32 {
312+
let n = fruits.len();
313+
let inf = 1 << 29;
314+
let mut f = vec![vec![-inf; n]; n];
315+
316+
f[0][n - 1] = fruits[0][n - 1];
317+
for i in 1..n {
318+
for j in i + 1..n {
319+
f[i][j] = std::cmp::max(f[i - 1][j], f[i - 1][j - 1]) + fruits[i][j];
320+
if j + 1 < n {
321+
f[i][j] = std::cmp::max(f[i][j], f[i - 1][j + 1] + fruits[i][j]);
322+
}
323+
}
324+
}
325+
326+
f[n - 1][0] = fruits[n - 1][0];
327+
for j in 1..n {
328+
for i in j + 1..n {
329+
f[i][j] = std::cmp::max(f[i][j - 1], f[i - 1][j - 1]) + fruits[i][j];
330+
if i + 1 < n {
331+
f[i][j] = std::cmp::max(f[i][j], f[i + 1][j - 1] + fruits[i][j]);
332+
}
333+
}
334+
}
335+
336+
let mut ans = f[n - 2][n - 1] + f[n - 1][n - 2];
337+
for i in 0..n {
338+
ans += fruits[i][i];
339+
}
340+
341+
ans
342+
}
343+
}
125344
```
126345

127346
<!-- tabs:end -->

0 commit comments

Comments
 (0)