Skip to content

feat: add solutions to lc problem: No.3205 #3200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
288 changes: 288 additions & 0 deletions solution/3200-3299/3205.Maximum Array Hopping Score I/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
---
comments: true
difficulty: 中等
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README.md
---

<!-- problem:start -->

# [3205. Maximum Array Hopping Score I 🔒](https://leetcode.cn/problems/maximum-array-hopping-score-i)

[English Version](/solution/3200-3299/3205.Maximum%20Array%20Hopping%20Score%20I/README_EN.md)

## 题目描述

<!-- description:start -->

<p>Given an array <code>nums</code>, you have to get the <strong>maximum</strong> score starting from index 0 and <strong>hopping</strong> until you reach the last element of the array.</p>

<p>In each <strong>hop</strong>, you can jump from index <code>i</code> to an index <code>j &gt; i</code>, and you get a <strong>score</strong> of <code>(j - i) * nums[j]</code>.</p>

<p>Return the <em>maximum score</em> you can get.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">nums = [1,5,8]</span></p>

<p><strong>Output:</strong> <span class="example-io">16</span></p>

<p><strong>Explanation:</strong></p>

<p>There are two possible ways to reach the last element:</p>

<ul>
<li><code>0 -&gt; 1 -&gt; 2</code> with a score of&nbsp;<code>(1 - 0) * 5 + (2 - 1) * 8 = 13</code>.</li>
<li><code>0 -&gt; 2</code> with a score of&nbsp;<code>(2 - 0) * 8 =&nbsp;16</code>.</li>
</ul>
</div>

<p><strong class="example">Example 2:</strong></p>

<div class="example-block">
<p><strong>Input:</strong> <span class="example-io">nums = [4,5,2,8,9,1,3]</span></p>

<p><strong>Output:</strong> <span class="example-io">42</span></p>

<p><strong>Explanation:</strong></p>

<p>We can do the hopping <code>0 -&gt; 4 -&gt; 6</code> with a score of&nbsp;<code>(4 - 0) * 9 + (6 - 4) * 3 = 42</code>.</p>
</div>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
<li><code>2 &lt;= nums.length &lt;= 10<sup>3</sup></code></li>
<li><code>1 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li>
</ul>

<!-- description:end -->

## 解法

<!-- solution:start -->

### 方法一:记忆化搜索

我们设计一个函数 $\text{dfs}(i)$,表示从下标 $i$ 出发,能够获得的最大分数。那么答案就是 $\text{dfs}(0)$。

函数 $\text{dfs}(i)$ 的执行过程如下:

我们枚举下一个跳跃的位置 $j$,那么从下标 $i$ 出发,能够获得的分数就是 $(j - i) \times \text{nums}[j]$,加上从下标 $j$ 出发,能够获得的最大分数,总分数就是 $(j - i) \times \text{nums}[j] + \text{dfs}(j)$。我们枚举所有的 $j$,取分数的最大值即可。

为了避免重复计算,我们使用记忆化搜索的方法,将已经计算过的 $\text{dfs}(i)$ 的值保存起来,下次直接返回即可。

时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def maxScore(self, nums: List[int]) -> int:
@cache
def dfs(i: int) -> int:
return max(
[(j - i) * nums[j] + dfs(j) for j in range(i + 1, len(nums))] or [0]
)

return dfs(0)
```

#### Java

```java
class Solution {
private Integer[] f;
private int[] nums;
private int n;

public int maxScore(int[] nums) {
n = nums.length;
f = new Integer[n];
this.nums = nums;
return dfs(0);
}

private int dfs(int i) {
if (f[i] != null) {
return f[i];
}
f[i] = 0;
for (int j = i + 1; j < n; ++j) {
f[i] = Math.max(f[i], (j - i) * nums[j] + dfs(j));
}
return f[i];
}
}
```

#### C++

```cpp
class Solution {
public:
int maxScore(vector<int>& nums) {
int n = nums.size();
vector<int> f(n);
auto dfs = [&](auto&& dfs, int i) -> int {
if (f[i]) {
return f[i];
}
for (int j = i + 1; j < n; ++j) {
f[i] = max(f[i], (j - i) * nums[j] + dfs(dfs, j));
}
return f[i];
};
return dfs(dfs, 0);
}
};
```

#### Go

```go
func maxScore(nums []int) int {
n := len(nums)
f := make([]int, n)
var dfs func(int) int
dfs = func(i int) int {
if f[i] > 0 {
return f[i]
}
for j := i + 1; j < n; j++ {
f[i] = max(f[i], (j-i)*nums[j]+dfs(j))
}
return f[i]
}
return dfs(0)
}
```

#### TypeScript

```ts
function maxScore(nums: number[]): number {
const n = nums.length;
const f: number[] = Array(n).fill(0);
const dfs = (i: number): number => {
if (f[i]) {
return f[i];
}
for (let j = i + 1; j < n; ++j) {
f[i] = Math.max(f[i], (j - i) * nums[j] + dfs(j));
}
return f[i];
};
return dfs(0);
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- solution:start -->

### 方法二:动态规划

我们可以将方法一中的记忆化搜索转换为动态规划。

定义 $f[j]$ 表示从下标 $0$ 出发,到下标 $j$ 结束,能够获得的最大分数。那么答案就是 $f[n - 1]$。

状态转移方程为:

$$
f[j] = \max_{0 \leq i < j} \{ f[i] + (j - i) \times \text{nums}[j] \}
$$

时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。

<!-- tabs:start -->

#### Python3

```python
class Solution:
def maxScore(self, nums: List[int]) -> int:
n = len(nums)
f = [0] * n
for j in range(1, n):
for i in range(j):
f[j] = max(f[j], f[i] + (j - i) * nums[j])
return f[n - 1]
```

#### Java

```java
class Solution {
public int maxScore(int[] nums) {
int n = nums.length;
int[] f = new int[n];
for (int j = 1; j < n; ++j) {
for (int i = 0; i < j; ++i) {
f[j] = Math.max(f[j], f[i] + (j - i) * nums[j]);
}
}
return f[n - 1];
}
}
```

#### C++

```cpp
class Solution {
public:
int maxScore(vector<int>& nums) {
int n = nums.size();
vector<int> f(n);
for (int j = 1; j < n; ++j) {
for (int i = 0; i < j; ++i) {
f[j] = max(f[j], f[i] + (j - i) * nums[j]);
}
}
return f[n - 1];
}
};
```

#### Go

```go
func maxScore(nums []int) int {
n := len(nums)
f := make([]int, n)
for j := 1; j < n; j++ {
for i := 0; i < j; i++ {
f[j] = max(f[j], f[i]+(j-i)*nums[j])
}
}
return f[n-1]
}
```

#### TypeScript

```ts
function maxScore(nums: number[]): number {
const n = nums.length;
const f: number[] = Array(n).fill(0);
for (let j = 1; j < n; ++j) {
for (let i = 0; i < j; ++i) {
f[j] = Math.max(f[j], f[i] + (j - i) * nums[j]);
}
}
return f[n - 1];
}
```

<!-- tabs:end -->

<!-- solution:end -->

<!-- problem:end -->
Loading
Loading