Skip to content

feat: add solutions to lc problem: No.3180 #3093

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
Jun 12, 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
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,153 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:排序 + 记忆化搜索 + 二分查找

我们可以对奖励值数组 `rewardValues` 进行排序,然后使用记忆化搜索的方法求解最大总奖励。

我们定义一个函数 $\text{dfs}(x)$,表示当前总奖励为 $x$ 时,能够获得的最大总奖励。那么答案为 $\text{dfs}(0)$。

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

1. 二分查找数组 `rewardValues` 中第一个大于 $x$ 的元素的下标 $i$;
2. 遍历数组 `rewardValues` 中从下标 $i$ 开始的元素,对于每个元素 $v$,计算 $v + \text{dfs}(x + v)$ 的最大值。
3. 将结果返回。

为了避免重复计算,我们使用记忆化数组 `f` 记录已经计算过的结果。

时间复杂度 $O(n \times (\log n + M))$,空间复杂度 $O(M)$。其中 $n$ 是数组 `rewardValues` 的长度,而 $M$ 是数组 `rewardValues` 中的最大值的两倍。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def maxTotalReward(self, rewardValues: List[int]) -> int:
@cache
def dfs(x: int) -> int:
i = bisect_right(rewardValues, x)
ans = 0
for v in rewardValues[i:]:
ans = max(ans, v + dfs(x + v))
return ans

rewardValues.sort()
return dfs(0)
```

#### Java

```java

class Solution {
private int[] nums;
private Integer[] f;

public int maxTotalReward(int[] rewardValues) {
nums = rewardValues;
Arrays.sort(nums);
int n = nums.length;
f = new Integer[nums[n - 1] << 1];
return dfs(0);
}

private int dfs(int x) {
if (f[x] != null) {
return f[x];
}
int i = Arrays.binarySearch(nums, x + 1);
i = i < 0 ? -i - 1 : i;
int ans = 0;
for (; i < nums.length; ++i) {
ans = Math.max(ans, nums[i] + dfs(x + nums[i]));
}
return f[x] = ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int maxTotalReward(vector<int>& rewardValues) {
sort(rewardValues.begin(), rewardValues.end());
int n = rewardValues.size();
int f[rewardValues.back() << 1];
memset(f, -1, sizeof(f));
function<int(int)> dfs = [&](int x) {
if (f[x] != -1) {
return f[x];
}
auto it = upper_bound(rewardValues.begin(), rewardValues.end(), x);
int ans = 0;
for (; it != rewardValues.end(); ++it) {
ans = max(ans, rewardValues[it - rewardValues.begin()] + dfs(x + *it));
}
return f[x] = ans;
};
return dfs(0);
}
};
```

#### Go

```go
func maxTotalReward(rewardValues []int) int {
sort.Ints(rewardValues)
n := len(rewardValues)
f := make([]int, rewardValues[n-1]<<1)
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(x int) int {
if f[x] != -1 {
return f[x]
}
i := sort.SearchInts(rewardValues, x+1)
f[x] = 0
for _, v := range rewardValues[i:] {
f[x] = max(f[x], v+dfs(x+v))
}
return f[x]
}
return dfs(0)
}
```

#### TypeScript

```ts
function maxTotalReward(rewardValues: number[]): number {
rewardValues.sort((a, b) => a - b);
const search = (x: number): number => {
let [l, r] = [0, rewardValues.length];
while (l < r) {
const mid = (l + r) >> 1;
if (rewardValues[mid] > x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};
const f: number[] = Array(rewardValues.at(-1)! << 1).fill(-1);
const dfs = (x: number): number => {
if (f[x] !== -1) {
return f[x];
}
let ans = 0;
for (let i = search(x); i < rewardValues.length; ++i) {
ans = Math.max(ans, rewardValues[i] + dfs(x + rewardValues[i]));
}
return (f[x] = ans);
};
return dfs(0);
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,153 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Sorting + Memoization + Binary Search

We can sort the `rewardValues` array and then use memoization to solve for the maximum total reward.

We define a function $\text{dfs}(x)$, representing the maximum total reward that can be obtained when the current total reward is $x$. Thus, the answer is $\text{dfs}(0)$.

The execution process of the function $\text{dfs}(x)$ is as follows:

1. Perform a binary search in the `rewardValues` array for the index $i$ of the first element greater than $x$;
2. Iterate over the elements in the `rewardValues` array starting from index $i$, and for each element $v$, calculate the maximum value of $v + \text{dfs}(x + v)$.
3. Return the result.

To avoid repeated calculations, we use a memoization array `f` to record the results that have already been computed.

The time complexity is $O(n \times (\log n + M))$, and the space complexity is $O(M)$. Where $n$ is the length of the `rewardValues` array, and $M$ is twice the maximum value in the `rewardValues` array.

<!-- tabs:start -->

#### Python3

```python

class Solution:
def maxTotalReward(self, rewardValues: List[int]) -> int:
@cache
def dfs(x: int) -> int:
i = bisect_right(rewardValues, x)
ans = 0
for v in rewardValues[i:]:
ans = max(ans, v + dfs(x + v))
return ans

rewardValues.sort()
return dfs(0)
```

#### Java

```java

class Solution {
private int[] nums;
private Integer[] f;

public int maxTotalReward(int[] rewardValues) {
nums = rewardValues;
Arrays.sort(nums);
int n = nums.length;
f = new Integer[nums[n - 1] << 1];
return dfs(0);
}

private int dfs(int x) {
if (f[x] != null) {
return f[x];
}
int i = Arrays.binarySearch(nums, x + 1);
i = i < 0 ? -i - 1 : i;
int ans = 0;
for (; i < nums.length; ++i) {
ans = Math.max(ans, nums[i] + dfs(x + nums[i]));
}
return f[x] = ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int maxTotalReward(vector<int>& rewardValues) {
sort(rewardValues.begin(), rewardValues.end());
int n = rewardValues.size();
int f[rewardValues.back() << 1];
memset(f, -1, sizeof(f));
function<int(int)> dfs = [&](int x) {
if (f[x] != -1) {
return f[x];
}
auto it = upper_bound(rewardValues.begin(), rewardValues.end(), x);
int ans = 0;
for (; it != rewardValues.end(); ++it) {
ans = max(ans, rewardValues[it - rewardValues.begin()] + dfs(x + *it));
}
return f[x] = ans;
};
return dfs(0);
}
};
```

#### Go

```go
func maxTotalReward(rewardValues []int) int {
sort.Ints(rewardValues)
n := len(rewardValues)
f := make([]int, rewardValues[n-1]<<1)
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(x int) int {
if f[x] != -1 {
return f[x]
}
i := sort.SearchInts(rewardValues, x+1)
f[x] = 0
for _, v := range rewardValues[i:] {
f[x] = max(f[x], v+dfs(x+v))
}
return f[x]
}
return dfs(0)
}
```

#### TypeScript

```ts
function maxTotalReward(rewardValues: number[]): number {
rewardValues.sort((a, b) => a - b);
const search = (x: number): number => {
let [l, r] = [0, rewardValues.length];
while (l < r) {
const mid = (l + r) >> 1;
if (rewardValues[mid] > x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
};
const f: number[] = Array(rewardValues.at(-1)! << 1).fill(-1);
const dfs = (x: number): number => {
if (f[x] !== -1) {
return f[x];
}
let ans = 0;
for (let i = search(x); i < rewardValues.length; ++i) {
ans = Math.max(ans, rewardValues[i] + dfs(x + rewardValues[i]));
}
return (f[x] = ans);
};
return dfs(0);
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Solution {
public:
int maxTotalReward(vector<int>& rewardValues) {
sort(rewardValues.begin(), rewardValues.end());
int n = rewardValues.size();
int f[rewardValues.back() << 1];
memset(f, -1, sizeof(f));
function<int(int)> dfs = [&](int x) {
if (f[x] != -1) {
return f[x];
}
auto it = upper_bound(rewardValues.begin(), rewardValues.end(), x);
int ans = 0;
for (; it != rewardValues.end(); ++it) {
ans = max(ans, rewardValues[it - rewardValues.begin()] + dfs(x + *it));
}
return f[x] = ans;
};
return dfs(0);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
func maxTotalReward(rewardValues []int) int {
sort.Ints(rewardValues)
n := len(rewardValues)
f := make([]int, rewardValues[n-1]<<1)
for i := range f {
f[i] = -1
}
var dfs func(int) int
dfs = func(x int) int {
if f[x] != -1 {
return f[x]
}
i := sort.SearchInts(rewardValues, x+1)
f[x] = 0
for _, v := range rewardValues[i:] {
f[x] = max(f[x], v+dfs(x+v))
}
return f[x]
}
return dfs(0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
class Solution {
private int[] nums;
private Integer[] f;

public int maxTotalReward(int[] rewardValues) {
nums = rewardValues;
Arrays.sort(nums);
int n = nums.length;
f = new Integer[nums[n - 1] << 1];
return dfs(0);
}

private int dfs(int x) {
if (f[x] != null) {
return f[x];
}
int i = Arrays.binarySearch(nums, x + 1);
i = i < 0 ? -i - 1 : i;
int ans = 0;
for (; i < nums.length; ++i) {
ans = Math.max(ans, nums[i] + dfs(x + nums[i]));
}
return f[x] = ans;
}
}
Loading
Loading