专栏文章
P4597 序列 sequence
P4597题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mipfjbjb
- 此快照首次捕获于
- 2025/12/03 11:10 3 个月前
- 此快照最后确认于
- 2025/12/03 11:10 3 个月前
尝试给出一个比较严谨的贪心证明。
序列的最终状态一定是若干连续段,并且每个连续段的值是单调增的。
对于每个段,我们都有方法可以调整到最终状态的花费并使得最优。比如先对段内元素进行排序,然后从两端不断抽出元素,把它们差的绝对值累加,当剩余元素不足 个时停止。
这种方案的正确性容易证明:由绝对值的几何意义可知,线段上两点到它们之间任意一点的距离相同,所以只需要从外到内累加,它们的中位数一定能被取到,总数为偶数时取较小值作为中位数。
于是可以定义一个“中和” 操作:取一个二元组 ,满足 ,把他们同时调整为 之间的任意整数 ,花费为 。
由于最终每段互相独立且中位数单调递增,所以一定能通过“中和” 操作取到最优解。
但是仍有部分限制:“中和” 操作所选的数不能有重复,因为这相当于把三个数都限定为它们的中位数。比如取了 和 ,由于 同时属于 和 ,所以 都只能取值为 。
但稍作观察即可发现,只对 进行“中和” 操作即可达到更优的效果,不妨将其命名为“改接”。
尝试动态维护最优序列,若加入新数仍满足单调不降,那么把它作为一个自由元加入大根堆,若加入后不满足,就用“中和” 操作处理,花费为堆顶元素与其的差,弹出堆顶,并将这个数加入大根堆两次。
为什么是两次?原因很简单:如果想把这个数作为大数再与更小的数进行“中和” 操作,首先要通过“改接”,使其变成自由元,同时补上少的那部分花费,下一次才能用它进行“中和”。
这时大根堆中元素有两种类型:自由元和待“改接” 的元素。自由元的值就是它本身,而待“改接” 元素的存在说明这个元素(不妨设为 )与一个更大的数 进行了“中和”,那么这两个数的值域为 ,又因为要使最大值尽可能小,所以当前序列的最大值就是堆顶元素的值。
容易发现每次操作的代价一定是最少的,现在只需证明能通过这样操作得到合法序列。
加入后满足单调不降显然合法,只需证明加入后不满足仍成立,设堆顶元素值为 。
如果堆顶是自由元,直接“中和” 即可,因为两数仍然能取到 ,所以一定合法。
如果堆顶元素要进行“改接”,由于“改接” 前较大值的取值已经限定为 了,那么从它开始到末尾的所有值只能为 ,“改接” 后值域扩大,一定还能取到 ,并且新增自由元的值也是 ,所以合法。
纵上,处理完新元素后序列仍合法,同时因为每不操作一定最优且可以只用“中和” 操作得到最优解,所以该算法正确。
代码已经有很多了,这里就不粘了。
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...