Loading

4.30 CW 模拟赛 T3. 蛋糕

前言

太久没看, 好像要重新想了
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠤⢄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⢀⣠⣶⣿⣿⠷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣦⣠⣶⣿⣿⣿⣿⣿⡦⠈⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⡏⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⡿⠸⢧⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⡇⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣟⣛⣛⣿⣿⣯⣭⣛⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠤⣶⣦⣭⣉⣁⠀⠀⠀⣐⣒⣠⣤⣤⣭⣶⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠄⠒⣹⣷⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠈⠁⠒⢢⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢰⠀⠀⠀⠀⠉⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠄⠀⠀⢀⡀⢠⣿⣿⠿⠛⠛⡉⢡⠈⣧⠐⢠⣿⠀⢸⡇⠀⠍⢉⠛⠿⢿⣿⡎⣀⣤⡀⡤⢐⣶⠚⢷⡀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠴⠁⠀⠀⠈⢿⡟⢸⣿⣷⡀⢋⡀⢧⠠⠐⢿⡇⢸⡇⢨⠘⠇⠄⠀⣿⠏⣰⣤⣿⣷⢻⣿⠁⠀⠀⠙⠷⠬⡇⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠊⠁⠀⠀⠀⠀⠀⣸⣧⣿⣿⣿⣷⣈⣥⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣯⣄⣿⣿⣿⣿⣸⣿⠀⠀⠀⠀⠀⠀⠘⢦⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⠟⠛⠛⠛⠛⠻⣿⣿⣿⣿⣿⣿⠛⠛⠛⢿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⢀⣀⣱⡄⠀⠀⠀
⠀⠀⠀⠀⢀⠄⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣿⠏⠀⣿⣿⣿⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⡿⠃⠀⠀⠀⢺⣿⣿⣿⣿⣿⣿⢿⣃⡦⠀⢀⣴⣿⣿⣿⣿⣿⣆⠀⠀
⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⣠⠴⠚⢩⡟⠁⠀⠀⣿⣿⣿⣀⣀⣠⠟⠀⠀⢀⣿⣿⡟⠁⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⡏⠘⢹⡇⠑⣸⣿⣿⣿⣿⣿⣿⣿⡆⠀
⠀⢠⠋⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠈⠀⠀⠀⢠⣿⣿⣿⣿⣿⠋⠀⠀⣠⣿⣿⡋⠀⠀⠐⠃⠀⠀⠈⣿⣿⣿⣿⣿⠀⠀⢻⡇⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⡀
⢀⠃⣀⡀⢀⠀⠀⠀⢀⣤⡶⠟⠁⠀⠀⠀⠀⠀⠸⣿⣿⣿⡿⠁⠀⢀⣾⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⠀⠀⠘⡇⠀⠀⠈⠹⣿⣿⣿⣿⣿⣿⡇
⠘⣾⣯⣤⣾⣄⠀⠀⠿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⠀⠀⠀⠛⠀⠀⢸⣿⣿⣿⣿⡿⠃⠀⠀⠘⣿⣿⣿⣿⣿⠀⠀⠀⠃⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⠇
⠀⠹⣾⣿⣿⣿⣆⠀⠀⠻⣄⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⡇⠀⠀⠀⠀⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⡿⠀
⠀⠀⠈⢦⠈⠙⣿⡆⠀⠀⠘⢧⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⢀⡆⠀⠀⣾⣿⣿⣿⣿⣿⣿⠃⠀
⠀⠀⠀⠀⠱⡄⠑⠻⣴⠀⠀⠘⣧⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢀⣾⠁⠀⠀⣿⣿⣿⣿⣿⣿⠃⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠑⢆⡀⠀⠹⣇⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡃⠀⠀⢰⣿⣿⣿⣿⡿⠁⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⡄⠀⢹⣷⣄⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⣠⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢄⠈⠦⣿⣿⣿⣦⣤⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⢄⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠈⢻⣿⣿⣿⣿⠿⠿⡿⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠦⣘⠻⠟⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⢤⣿⣿⡛⠷⠆⠜⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⢄⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠘⠻⢿⠗⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢰⠀⠀⠈⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣇⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣿⣆⠀⡞⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠾⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠃⠀⢨⣿⠀⢹⣼⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

思路

不难发现可以将吃行的操作视为对吃列的操作的一个优化
于是可以考虑 \(f_{i, j}\) 表示前 \(i\) 列, \(1 \sim i\) 列吃了 \(j\) 行的最小花费

不难发现

\[f_{i, j} \xleftarrow[]{0 \leq k \leq j} f_{i - 1, j - k} + k \times c_i + \max\{0, a_i - j\} \]

其中 \(c_i = \min_{k = i}^{n} a_k\)

考虑优化
注意到疑似可以使用类无限背包的优化
首先考虑到在 \(i\) 位置上一旦 \(j \geq a_i\) 就不用放了, 否则放一个的花费很好算

感觉到这个东西是不是可以费用提前计算啊, 发现没有用啊不管了, 本身贡献计算没有带来任何多余的复杂度

于是可以简单地把柿子变成

\[ \begin{gather*} f_{i, j} + c_i - 1 \xrightarrow[]{\min} f_{i, j + 1} & (j < a_i) \\ f_{i, j} + \max\{a_{i + 1} - j, 0\} \xrightarrow[]{\min} f_{i + 1, j} \end{gather*} \]

最终的答案显然是 \(f_{n, \boxed{}}\)


以上可以通过 \(n \leq 5000, a_i \leq 5000\) 的数据


考虑优化
先把柿子甩出来

\[ \begin{gather} f_{i, j} + c_i - 1 \xrightarrow[]{\min} f_{i, j + 1} & (j < a_i) \\ f_{i, j} + \max\{a_{i + 1} - j, 0\} \xrightarrow[]{\min} f_{i + 1, j} \end{gather} \]

传统优化不可能
要整点新活

考虑行间和列间转移互相无关, 不妨先把 \(f_{i + 1}(j)\) 赋为 \(f_{i}(j) + \max\{a_{i + 1} - j, 0\}\), 然后再去处理 \((1)\) 柿, 显然是可以这样做的
注意到 \((1)\) 柿是对差分数组的区间取 \(\min\), 这个意义下的 \((2)\) 柿可以表示为对差分数组的前缀 \(-1\) 和全局加

那么不难发现差分数组单增, 考虑类似凸函数的维护
首先, \(f_{0}(0) = 1\)
第一轮 \(f_{1}(0) = a_1\), 根据 \((1)\) 柿直接推出一条 \(c_i - 1\) 斜率的直线
第二轮首先继承 \(f_{1}\) 再加上一个 \(\max\{a_2 - j, 0\}\), 简单模拟一下
pEvkwRg.png
第三轮同理, 首先继承 \(f_{2}\) 再加上一个 \(\max\{a_3 - j, 0\}\), 显然是在原来的基础上分开, 左边斜率减一, 右边不变
然后再用一条斜率为 \(c_3 - 1\) 的直线去更新, 相当于把某段直线推平为 \(c_3 - 1\) 斜率

于是利用 \(\textrm{slope trick}\) 维护, 每次更新的时候先继承加个断点
然后不断推平一段后缀, 直到斜率小于 \(c_i - 1\) 为止

最终的答案怎么计算?
显然动态维护每条线段的结束端点的 \(y\) 坐标即可

总结

尝试把交错的 \(\rm{dp}\) 转移关系理清楚, 掏出来

其实这种多了少了都不优, 只有中间某个位置最优的情况, 尝试一下能不能转成凸包

\(\max\{kx + b, C\}\) 其实也是一段直线
\(f_i(x)\)\(f_i(x + 1)\) 的转移, 本质上是对每个点延伸出去一条直线取 \(\min\) 或者 \(\max\)

这个优化方式其实也没得说了
多画图观察变化

一个很经典的结论: 两条直线相加, 其斜率为两条直线的斜率之和, 截距为两条直线的截距之和

posted @ 2025-05-16 21:13  Yorg  阅读(17)  评论(0)    收藏  举报