[R37B]生日蛋糕


2≤n≤1002 \le n \le 100,1≤ai≤1091 \le a_i \le 10^9,保证 aia_i 互不相同。

思路

题目要求选一段长度至少为 22 的连续子数组,使其中 最大值与次大值之差 最大化。

直接证明一个很强的结论:答案等于所有相邻元素差值的绝对值的最大值,即 max⁡i∣ai−ai+1∣\max_i |a_i - a_{i+1}|。

  • 下界:任意长度为 22 的子数组 [ai,ai+1][a_i, a_{i+1}] 都是合法选择,此时最大值与次大值之差就是 ∣ai−ai+1∣|a_i - a_{i+1}|,所以答案至少为 max⁡i∣ai−ai+1∣\max_i |a_i - a_{i+1}|。
  • 上界:对任意一个长度 ≥2\ge 2 的连续子数组 SS,设其最大值为 MM(位于位置 pp)。由于 aia_i 互不相同,MM 是 SS 中唯一的最大值。因为 SS 长度至少为 22,位置 pp 在 SS 内必然至少有一个相邻元素 aja_j(左邻或右邻)。由 aj∈Sa_j \in S 且 aj<Ma_j < M,而次大值 m2m_2 是 SS 中除 MM 外的最大元素,故 aj≤m2a_j \le m_2。于是
M−m2≤M−aj=∣ap−aj∣,M - m_2 \le M - a_j = |a_p - a_j|,

而 ap,aja_p, a_j 是原数组中相邻的两个元素,所以 M−m2M - m_2 不超过某个相邻差值的绝对值。上界得证。

因此只需一遍扫描所有相邻对,取绝对值差的最大值即可,无需暴力枚举所有子数组。

复杂度

时间 O(n)O(n),空间 O(n)O(n)(存输入数组)。n≤100n \le 100 远低于上限。

仓颉实现

查看仓颉实现
import std.console.*
import std.convert.*

main() {
    let reader = Console.stdIn
    let n = Int64.parse(reader.readln().getOrThrow())
    let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
    var ans: Int64 = 0
    var i = 1
    while (i < n) {
        let d = a[i] - a[i - 1]
        var absd = d
        if (d < 0) {
            absd = -d
        }
        if (absd > ans) {
            ans = absd
        }
        i += 1
    }
    println(ans)
}