1 条题解
-
0
题解
问题分析
这是一个动态规划 + 双端队列优化的问题。我们需要对每个前缀 计算灌溉前 株植物的最小费用。
关键观察
- 水渠特性:水渠 同时灌溉植物 和 ,费用为
- 水量约束:每个植物 需要至少 单位水
- 费用函数:费用是关于水量的分段线性凸函数
算法思路
维护凸包 + 双端队列优化:
数据结构设计
I结构:维护凸包的双端队列,支持反转和线性变换x:存储水量转折点k:存储斜率变化量f0,fv:函数在 0 和 V 处的值d0,dv:函数在 0 和 V 处的斜率
核心操作
- 斜率调整:当 时,从左侧移除负斜率段
- 水量约束:当 时,从右侧调整以满足新植物的水量需求
- 状态转移:添加新水渠时更新费用函数
算法步骤
- 初始化:处理第一株植物
- 循环处理:对于每个新植物 到 :
- 调整左侧负斜率
- 调整右侧满足水量约束
- 输出当前前缀的最小费用
- 添加新水渠,更新状态
复杂度分析
- 每个植物:均摊 次队列操作
- 总复杂度:
关键函数说明
I结构操作Rev():反转队列顺序Apply(x):应用线性变换F(x),If(x):正向/反向坐标变换
水量约束处理
while (!x.Empty() && x.Back() >= w[i]) { fv -= dv * (lst - x.Back()); lst = x.Back(); dv -= k.Back(); x.PopBack(); k.PopBack(); }负斜率修正
while (d0 < 0) { f0 += d0 * (x.Front() - lst); lst = x.Front(); d0 += k.Front(); x.PopFront(); k.PopFront(); }样例验证
样例1:
- 前2株:使用水渠1 69次,费用
- 前3株:水渠1 39次 + 水渠2 33次,费用
- 输出正确
样例2:
- 前2株:水渠1 82次,费用
- 前3株:优化后费用 676
- 输出正确
算法标签
- 动态规划
- 凸包维护
- 双端队列优化
- 分段线性函数
- 斜率优化
- 1
信息
- ID
- 3977
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者