参考。
例题
序列 Sequence
分析
很显然的,我们可以得到一个 的 DP 做法。定义状态函数 表示前 个数, 的最小操作次数。其中 为原序列排序去重的结果。那么有转移方程:。
不难发现,我们的 是一个凸函数。因为对于 的增加,我们有 ,证明略。而对于形如 的函数,也是一个凸函数。对于一个凸函数 ,我们用 来表示。具体的,当 与 之间的斜率为 时,我们可以用 个 来表示在 到 的过程中,斜率增加量为 。其中第 个 表示了这个点。这样,我们就直接把这个凸函数的形状表示出来了,只需要知道任意一个 的值就能得到所有函数值。
那么对于这道题,斜率 的最大值为 ,因为我们取了前缀 。那么由于两个凸函数相加的结果为凸函数,则可以直接通过插入 的方式更新函数的表示。如果我们 这个点对应的更新之前的函数是在一个相邻斜率为 的区间内,则插入单点 就能表示。如果不是,那么在 之前的点斜率减少 ,之后的斜率增加 ,再与 取最小值。我们控制前面的斜率不变,则能够用 个 表示出斜率加 。而加 之后的分界点(之后的点斜率大于 )就是当前所有 中的最大值了。(貌似是的?)那么我们就只需要将最大值删除,再加入 个 来更新形状。
对于这道题,不难发现答案就是维护出的函数中,斜率为 时的纵坐标。那么对于斜率变化的情况,我们的纵坐标相当于是整体加上了最大值减去 。斜率不变的情况不变。维护插入、删除、最大值可以直接使用优先队列。时间复杂度 。
代码
for(re int i=1;i<=n;++i){
if(!qu.empty()&&qu.top()>a[i]) ans+=qu.top()-a[i],qu.pop(),qu.push(a[i]);
qu.push(a[i]);
}
Sonya and Problem Wihtout a Legend
不难定义出状态 表示前 个数,第 个数为 的最小操作次数。那么有:。那么直接优化可以做到 。因为我们要保证单增,而下标 也是单增的,所以令 就只需要保证修改之后的 不降。其余同 Sequence。
Making the Grade G
正反跑 遍即可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性