1 条题解

  • 0
    @ 2026-4-19 14:55:44

    题目理解

    我们有一个非递减排序的数组 aa
    我们可以移除任意元素(包括不移除),然后按照规则将剩余元素分配到不同的数组中:

    • 第一个元素 a1a_1 总是开始一个新的数组;
    • 对于 i2i \ge 2,如果 ai1+1<aia_{i-1} + 1 < a_i,那么 aia_i 开始一个新数组;否则,aia_i 加入 ai1a_{i-1} 所在的数组。

    目标:通过移除一些元素,使最终得到的数组个数最大。


    关键观察

    1. 第一个元素必须保留
      如果去掉 a1a_1,那么新的第一个元素 aja_jj2j \ge 2)的值只会更大或相等,不会让答案变好。保留 a1a_1 可以尽早开始计数。

    2. 跳跃规则
      规则本质是:
      若当前元素 xx 与上一个保留的元素 lastlast 满足:
      [ x - last > 1 ]
      xx 会开始一个新的数组。否则,它加入前一个数组。

    3. 贪心策略
      我们希望在保留元素的过程中,尽可能多地触发“xlast>1x - last > 1”的条件。
      因此,一旦某个元素与上一个保留元素的差大于 1,我们就保留它,并让它开始一个新数组。
      如果差 1\le 1,我们可以选择跳过它,因为跳过它不会破坏后面的可能性,甚至可能让后面的元素更容易满足条件(例如跳过 x+1x+1 可以让 x+2x+2 相对上一个保留元素形成更大的差)。

    4. 为什么跳过更小的差不会变差
      假设上一个保留元素是 lastlast,当前元素是 ai=last+1a_i = last + 1

      • 如果保留它,它会加入 lastlast 所在的数组,不增加数组数,且下一个可能元素是 last+2last+2,差为 1,仍不满足 >1>1
      • 如果跳过它,下一个元素 ai+1last+2a_{i+1} \ge last+2,与 lastlast 的差 2\ge 2,会触发新数组。
        因此跳过不会让答案变小。

    算法步骤

    1. 初始化 last=1last = -1(因为 ai1a_i \ge 1,所以 1-1 可以确保第一个元素一定满足条件)。
    2. 初始化 ans=0ans = 0
    3. 遍历数组 aa 的每个元素 xx
      • 如果 xlast>1x - last > 1
        • 增加 ansans(表示 xx 开始一个新数组)
        • 更新 last=xlast = x
      • 否则(xlast1x - last \le 1):
        • 跳过 xx(不更新 lastlast,也不增加 ansans
    4. 输出 ansans

    示例验证

    示例 1

    a=[1,2,3,4,5,6]a = [1,2,3,4,5,6]

    • x=1x=11(1)=2>11 - (-1) = 2 > 1ans=1,last=1ans=1, last=1
    • x=2x=221=112-1=1 \le 1 → 跳过
    • x=3x=331=2>13-1=2>1ans=2,last=3ans=2, last=3
    • x=4x=443=114-3=1\le1 → 跳过
    • x=5x=553=2>15-3=2>1ans=3,last=5ans=3, last=5
    • x=6x=665=116-5=1\le1 → 跳过
      输出 33,与题目一致。

    示例 3

    a=[1,2,2,4]a = [1,2,2,4]

    • x=1x=1ans=1,last=1ans=1, last=1
    • x=2x=221=12-1=1 → 跳过
    • x=2x=221=12-1=1 → 跳过
    • x=4x=441=3>14-1=3>1ans=2,last=4ans=2, last=4
      输出 22,正确。

    示例 5

    a=[1,4,8]a = [1,4,8]

    • x=1x=1ans=1,last=1ans=1, last=1
    • x=4x=441=3>14-1=3>1ans=2,last=4ans=2, last=4
    • x=8x=884=4>18-4=4>1ans=3,last=8ans=3, last=8
      输出 33,正确。

    复杂度分析

    • 每个元素只处理一次,O(n)O(n) 时间。
    • 仅使用常数个变量,O(1)O(1) 额外空间。
    • nn 不超过 2×1052 \times 10^5,可轻松通过。

    总结

    题目的贪心策略是:
    只要当前元素与上一个保留元素的差值大于 1,就保留它并增加数组计数;否则跳过它。
    这样可以在保留第一个元素的基础上,最大化“新数组”的触发次数。

    • 1

    信息

    ID
    6587
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者