2025.04.08 CW 模拟赛 A. 序列加法机

题面 & 题解.

A. 序列加法机

Trick 是之前见到过的. 来源.

题目描述

A 酱发明了序列加法机,它的作用是把一个长度为 \(n\) 的单调不降序列 \(a\) 转换成另一个长度为 \(n\) 的单调不降序列 \(b\)。不过由于序列加法机的功能还不完善,现在它只能执行不超过 \(m\) 次以下操作:

  • 选择一个 \(1 \leq i \leq n\) 和一个整数 \(x\),将 \(a_i\) 加上 \(x(x \text{ 可以 } < 0)\),操作代价是 \(x^2\)

并且序列加法机还需要保证每次操作完成后,\(a\) 依然是单调不降的,那么序列加法机最少需要多少代价才能将 \(a\) 转换成 \(b\)

思路

首先我们转化一下题意

  • 我们令 \(d_i = |a_i - b_i|\), 我们需要将所有 \(d_i\) 拆分成至多 \(m\) 个数, 形成形如 \(x_1, x_2, \dots, x_m\) 的序列, 最后让 \(\sum x_i^2\) 最小.

我们令 \(F_k(x)\) 表示将数字 \(x\) 拆分成 \(k\) 份的最小代价, 显然将 \(x\) 尽量平均拆分一定是最优的, 并且对于单个 \(x\), \(F_i(x)\) 是随着 \(i\) 的增加而减小的, 并且具有凸性. 具体来说, 设 \(\Delta_k = F_{k + 1}(x) - F_{k}(x)\), 那么 \(\Delta_i \ge \Delta_{i + 1}\), 亦即 \(\Delta\) 数组是递减的.

对于每一个 \(d_i\), 我们多操作一次便会增加一个差量 \(\Delta_k\). 由于我们想让最终答案尽量小, 那么每次就需要贪心的使得增加的差量尽量小 \((\)因为差量是负数\()\).

发现这不难用堆进行维护. 在实现上, 我们将每个数的 \(\Delta_1\) 先存进小根堆里, 每次取出堆顶, 然后将这个数的 \(\Delta_2\) 放进去, 以此类推, 直到操作数等于 \(m\).

posted @ 2025-04-09 07:54  Steven1013  阅读(94)  评论(0)    收藏  举报