comments | difficulty | edit_url | rating | source | tags | ||
---|---|---|---|---|---|---|---|
true |
中等 |
1692 |
第 415 场周赛 Q2 |
|
给你一个大小为 4 的整数数组 a
和一个大小 至少为 4 的整数数组 b
。
你需要从数组 b
中选择四个下标 i0
, i1
, i2
, 和 i3
,并满足 i0 < i1 < i2 < i3
。你的得分将是 a[0] * b[i0] + a[1] * b[i1] + a[2] * b[i2] + a[3] * b[i3]
的值。
返回你能够获得的 最大 得分。
示例 1:
输入: a = [3,2,5,6], b = [2,-6,4,-5,-3,2,-7]
输出: 26
解释:
选择下标 0, 1, 2 和 5。得分为 3 * 2 + 2 * (-6) + 5 * 4 + 6 * 2 = 26
。
示例 2:
输入: a = [-1,4,5,-2], b = [-5,-1,-3,-2,-4]
输出: -1
解释:
选择下标 0, 1, 3 和 4。得分为 (-1) * (-5) + 4 * (-1) + 5 * (-2) + (-2) * (-4) = -1
。
提示:
a.length == 4
4 <= b.length <= 105
-105 <= a[i], b[i] <= 105
我们设计一个函数
函数
- 如果
$j \geq \text{len}(b)$ ,表示数组$b$ 已经遍历完了,此时如果数组$a$ 也遍历完了,返回$0$ ,否则返回负无穷; - 如果
$i \geq \text{len}(a)$ ,表示数组$a$ 已经遍历完了,返回$0$ ; - 否则,我们可以不选择数组
$b$ 的第$j$ 个元素,直接跳到下一个元素,即$\textit{dfs}(i, j + 1)$ ;也可以选择数组$b$ 的第$j$ 个元素,此时得分为$a[i] \times b[j]$ ,再加上$\textit{dfs}(i + 1, j + 1)$ 。我们取这两者的最大值作为$\textit{dfs}(i, j)$ 的返回值。
我们可以使用记忆化搜索的方式,避免重复计算。
时间复杂度
class Solution:
def maxScore(self, a: List[int], b: List[int]) -> int:
@cache
def dfs(i: int, j: int) -> int:
if j >= len(b):
return 0 if i >= len(a) else -inf
if i >= len(a):
return 0
return max(dfs(i, j + 1), a[i] * b[j] + dfs(i + 1, j + 1))
return dfs(0, 0)
class Solution {
private Long[][] f;
private int[] a;
private int[] b;
public long maxScore(int[] a, int[] b) {
f = new Long[a.length][b.length];
this.a = a;
this.b = b;
return dfs(0, 0);
}
private long dfs(int i, int j) {
if (j >= b.length) {
return i >= a.length ? 0 : Long.MIN_VALUE / 2;
}
if (i >= a.length) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
return f[i][j] = Math.max(dfs(i, j + 1), 1L * a[i] * b[j] + dfs(i + 1, j + 1));
}
}
class Solution {
public:
long long maxScore(vector<int>& a, vector<int>& b) {
int m = a.size(), n = b.size();
long long f[m][n];
memset(f, -1, sizeof(f));
auto dfs = [&](this auto&& dfs, int i, int j) -> long long {
if (j >= n) {
return i >= m ? 0 : LLONG_MIN / 2;
}
if (i >= m) {
return 0;
}
if (f[i][j] != -1) {
return f[i][j];
}
return f[i][j] = max(dfs(i, j + 1), 1LL * a[i] * b[j] + dfs(i + 1, j + 1));
};
return dfs(0, 0);
}
};
func maxScore(a []int, b []int) int64 {
m, n := len(a), len(b)
f := make([][]int64, m)
for i := range f {
f[i] = make([]int64, n)
for j := range f[i] {
f[i][j] = -1
}
}
var dfs func(i, j int) int64
dfs = func(i, j int) int64 {
if j >= n {
if i >= m {
return 0
}
return math.MinInt64 / 2
}
if i >= m {
return 0
}
if f[i][j] != -1 {
return f[i][j]
}
f[i][j] = max(dfs(i, j+1), int64(a[i])*int64(b[j])+dfs(i+1, j+1))
return f[i][j]
}
return dfs(0, 0)
}
function maxScore(a: number[], b: number[]): number {
const [m, n] = [a.length, b.length];
const f: number[][] = Array.from({ length: m }, () => Array(n).fill(-1));
const dfs = (i: number, j: number): number => {
if (j >= n) {
return i >= m ? 0 : -Infinity;
}
if (i >= m) {
return 0;
}
if (f[i][j] !== -1) {
return f[i][j];
}
return (f[i][j] = Math.max(dfs(i, j + 1), a[i] * b[j] + dfs(i + 1, j + 1)));
};
return dfs(0, 0);
}