题目重点:用相邻差分建立下界,再用后缀增量构造达到下界;区分操作次数与增量总和。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 只允许增加,每次增加任意连续区间,增量 x 为正整数;成本为 x 而非一次调用算 1。
- 只要求最终非递减,没有最终值上限或精确目标。
- 空数组与单元素返回 0;示例允许负的初始值,差分证明仍成立。
解题路线
- 记相邻下降缺口 d_i=max(0,a_i−a_{i+1})。任何区间加 x 只会在左边界提高一个差分,在右边界降低一个差分;为了修复某个原始负差分,必须有至少 d_i 的增量在该位置开始。
- 将所有负差分的必需增量相加,得到成本下界 Σd_i。一个操作只有一个左边界,不能用同一份成本同时修复两处原始下降。区间右边界还可能产生新下降,因此不会帮助降低这个下界。
- 构造达到下界:从左到右看原始相邻差,如果下降,就给该位置右侧的整个后缀加 d_i。此前后缀操作对这对相邻值同时加相同数,不改变原始差,当前操作恰好消除下降;没有右边界产生新的内部下降。
- 实现直接累加正下降量,无需修改输入,也无需逐次模拟。若需输出操作,记录 (i+1,n−1,d_i) 即可。
手动走一遍
题目例 [3,4,1,6,2] 有下降 4−1=3 与 6−2=4,成本 7。后缀 [2,4] 加 3 得 [3,4,4,9,5];后缀 [4,4] 加 4 得 [3,4,4,9,9]。若仅逐元素补到当前前缀最大,可能重复支付后续元素,失去区间共享收益。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def minimum_segment_increment_sum(power: list[int]) -> int:
"""One operation raises an arbitrary contiguous segment by positive x, costing x."""
return sum(max(0, left - right) for left, right in zip(power, power[1:]))
复杂度
O(n) 时间、O(1) 辅助空间。独立 oracle 对小数组使用所有 +1 区间操作的 BFS 求最短操作数,核对闭式答案;增量 x 可拆成 x 次单位操作,因此验证成本口径一致。
易错点与追问
容易失分的边界
- 把成本改成任意 x 的一次操作只付 1,这会变成不同问题。
- 累加元素到前缀最大值的缺口,而非原始相邻下降。
- 认为排序数组是合法操作。
- 输出操作时用半开/闭区间混淆下标。
继续深挖
- 若区间长度有上限,后缀构造还能成立吗?
- 允许减小且按绝对增量收费,答案如何变化?
- 有最终值上限时如何检测不可行?
