📌  相关文章
📜  最大化数组中 (a[i]+i)*(a[j]+j) 的值(1)

📅  最后修改于: 2023-12-03 15:10:35.140000             🧑  作者: Mango

最大化数组中 (a[i]+i)*(a[j]+j) 的值

当要求最大化一个表达式时,可以考虑使用数学推导和优化算法。这里我们考虑最大化数组中 $(a[i]+i)*(a[j]+j)$ 的值。

数学推导
  • 当 $i<j$ 时,

$(a[i]+i)*(a[j]+j) = (a[i]*a[j]+a[i]*j+a[j]i+ij)$

$=(a[i]a[j]+ij) + (a[i]+j) * (a[j]+i)$

  • 当 $i>j$ 时,

$(a[i]+i)*(a[j]+j) = (a[i]*a[j]+a[i]*j+a[j]i+ij)$

$=(a[i]a[j]+ij) + (a[j]+i) * (a[i]+j)$

可以发现,当 $i<j$ 时,$(a[i]a[j]+ij)$ 是常量,可以考虑使用前缀或后缀优化算法快速计算出来。也就是说,我们只需要在 $a[i]$ 加上下标 $i$ 的值后,再加上它后面的最大值,就可以求出当前的最大值。同理,在 $a[i]$ 加上下标 $i$ 的值后,再减去它前面的最小值,就可以求出后面的最大值。

在计算时,需要同时维护最小值和最大值,可以使用两个数组或一个单调队列来实现。

代码实现
def max_expr(arr: List[int]) -> int:
    n = len(arr)
    pre_min, pre_max = [float('inf')] * n, [float('-inf')] * n
    suf_min, suf_max = [float('inf')] * n, [float('-inf')] * n

    pre_min[0], pre_max[0] = arr[0], arr[0]
    for i in range(1, n):
        pre_min[i] = min(pre_min[i - 1], arr[i] - i)
        pre_max[i] = max(pre_max[i - 1], arr[i] - i)

    suf_min[n-1], suf_max[n-1] = arr[n-1], arr[n-1]
    for i in range(n - 2, -1, -1):
        suf_min[i] = min(suf_min[i + 1], arr[i] + i)
        suf_max[i] = max(suf_max[i + 1], arr[i] + i)

    res = float('-inf')
    for i in range(n):
        res = max(res, (arr[i] + i - pre_min[i]) * (arr[i] + i - pre_max[i]))
        res = max(res, (arr[i] - i - suf_min[i]) * (arr[i] - i - suf_max[i]))

    return res
结论

我们通过数学推导和优化算法,得到了最大化数组中 $(a[i]+i)*(a[j]+j)$ 的值的方法。代码实现中,需要使用两遍前缀或后缀预处理,以及一次遍历求最大值。时间复杂度为 $O(n)$,空间复杂度为 $O(n)$。

总之,当我们需要优化表达式的最值时,可以通过数学推导和算法优化,得到高效的实现方法。