11.20 CW 模拟赛 T3.货物分组

算法#

考虑 dp

fi,j 表示前 i 个数中, 分成 m 组的最小花费
关于转移, 我们有

fi,j=min(fk,j1+j×Sum(k+1,i)+max(k+1,i)min(k+1,i))

其中 Sum 可以前缀和预处理, max,min 可以 ST 表预处理
这样转移是 O(n3) 的, 考虑优化

这里是一个 trick , 即费用提前计算, 题面中花费 i×wsum 转化成每一次的花费都是 Sum(i+1,n)
dp 柿子转化成 dpi=min[dpj+Sum(j+1,n)+max(j+1,i)min(j+1,i))]
复杂度 O(n2) , 考虑优化转移

对于 Sum(j+1,n) 是定值, 我们考虑将其提出
方程转化成 dpi=Sum(j+1,n)+min[dpj+max(j+1,i)min(j+1,i))]

考虑令 gj=dpj+max(j+1,i)min(j+1,i)) , 维护 gj 最小值

这是可以维护的吗?

考虑线段树维护 g ,

对于每一次更新 dpi

我们可以在单调栈中找到每一段区间最大值小于 ai 最小的 j , 显然的, ji 这一段中, 区间最大值都需要更新
容易发现, 这就是单调栈所维护的基本信息, 本质上是找当前节点左侧第一个比自己大的元素, 用一个单调递减栈即可, 特别的, 对于这两个单调栈, 维护的都是前缀最值

于是我们只需要线段树维护区间最值 and 区间加法

复杂度 O(nlogn) , 常数稍大

代码#

第一次写单调栈维护

代码大致分为几个板块:

  • 维护区间最值, 有区间加法功能的线段树
  • 单调递减栈, 维护区间最大值小于 ai 的左端点, 单调递增栈, 维护区间最小值大于 ai 的左端点

注意单调栈事实上维护的是几段, 每一段线段树上更新的值都不同, 不能一次弄完

这几天状态真的不好, 但这题也是真的搞懂了, 懒得再去打代码和调了

总结#

费用提前计算是一个巧妙的 trick

注意 dp 不能仅仅简单的省略掉一维, 很有可能会导致正确性出现问题, 这个多练练应该可以解决

对于神秘转移式子, 考虑多来几种数据结构维护

单调栈/队列 是常见的数据结构维护

神秘维护, 诗人握持

posted @   Yorg  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示