不相邻取点最值问题

Problem

给定一个长度 nn 的整数序列 AA 现选取 mm 个点,使得这些点两两不相连,求最大和 (最小同理)

Solution

以最大值为例

策略:若当前状态最大值不选,则一定选择最大值左右两点

归纳法证明:

  1. m=1m = 1 , 选取最大值
  2. m=2m = 2 , 选取最大值和不相邻的次大值,或者选择最大值两侧的点

得证

算法流程如下:

  1. 建立一个大根堆,依次插入所有数
  2. 每次取出最大值,加入答案。记最大值下标为 ii , 修改 AiA_iAlc(i)+Arc(i)AiA_{lc(i)} + A_{rc(i)} - A_i , 并且加入堆,删除lc(i)lc(i)rc(i)rc(i)。其中 lc(i)rc(i)lc(i) 和 rc(i) 为链表,初始分别指向 i1i-1i+1i+1
  3. 重复 mm操作2

例题

[APIO/CTSC 2007]

hint

选相邻一定最优


生日礼物

hint

将所有正数和负数合并(0需要被忽略)

现选择所有正数段,记为 pp 个,若 pmp \leq m ,则直接输出,否则尝试删除 pmp-m 个正数

  1. 删除最小的正数,堆中加入该正数和左右两数的和,方便下次转移
  2. 合并两个正数,减去中间的数(绝对值),向堆中加入合并值

综上,选不相邻一定最优

注意:边界负数不选


Author: cjh-hhz
Link: https://cjh-hhz.github.io/ba2dd29b79c8.html/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.