The Endspeaker (Easy Version)
算法
题意没什么可以转化的,已经很明确了。
容易发现当 \(k\) 确定且要进行移除前缀操作时,一定要尽可能的使前缀更大不然一定不优。
考虑动态规划,令 \(dp_i\) 表示移除 \(a\) 数组的前 \(i\) 项所需的最小总成本。
可以发现 \(dp_i\) 可以从 \(dp_j, 0 \leq j < i\) 推出来,令 \(k\) 表示最大的 \(k\) 使得可以移除 \([j + 1, i]\) 这一前缀,如果 \(k\) 不存在则跳过这一转移。
但是注意到 \(k\) 始终不减,考虑新开一维表示当前的 \(k\) ,
这个柿子的复杂度是 \(\mathcal{O}(n^2m^2 \log m)\) 的,考虑优化。
手动模拟一下可以发现,\(k^{\prime} \leq k\) 条件带来了大量的重复计算,事实上,我们完全可以每次仅仅令 \(k = k^{\prime} + 1 \ \rm{or} \ k^{\prime}\) 。
现在我们的转移柿子变成了,
显而易见的,我们需要尽可能的使得 \(x, y\) 尽量小,并且满足 \(\textrm{Sum} (x + 1, i) , \textrm{Sum} (y + 1, i) \leq b_k\) ,二分可以处理。
初始化令 \(dp_{0, 1} = 0\) ,答案为 \(\displaystyle\min_{i = 1}^{m} {dp}_{n, i}\) ,特别的,当无法转移到答案时,输出 \(-1\)。
时间复杂度 \(\mathcal{O} (nm\log m)\) 。
这里顺手就把 \(\rm{Hard \ Version}\) 讲一下
注意到如果要统计方案数, 必须要在转移的时候更新区间而非仅仅只更新最优解
我们线段树维护区间修改, 然后统计 \(i = n\) 时的选择方案即可
考虑复习
这里只复习 \(\textrm{Easy Version}\) , 对方程式的一些优化
还是这个转移, 关于推出这个的方式, 其实更好的理解方法是, 分类成是否将 \(k\) 增加 \(1\)
根据定义不难发现, 不妨把 \(dp_{i, k}\) 的第二维看做一个定值, 那么 \(dp_k (i)\) 单调不降
更一般的, 对于 \(\displaystyle\varphi (i) = \min_{k = 1}^{m} {dp}_{i, k}\) , 不难发现 \(\varphi\) 函数单调不降, 但是这个没什么用
所以如果我们找出了 \(x, y\) 的取值区间, 相当于找到了转移最值
不难发现, 随着 \(i\) 增大, 如果一个 \(x\) 对于 \(i' < i\) 都有 \(\textrm{Sum} (x + 1, i') > b_k\) , 必有 \(\textrm{Sum} (x + 1, i) > b_k\) , 有单调性, 所以简单双指针维护可以做到 \(\mathcal{O} (mn)\)
代码
略
总结
观察题目数据可以大概构想出方程形式,
手动模拟可以找到算法劣在哪里。
这种转移, 考虑每次 \(+1\) 处理
一种当 \(dp\) 数组对应的函数单调不降 \((\)一般是由于定义, 当然也可以自己推导\()\) 的 \(\rm{trick}\) :
直接通过维护取值区间来维护转移最值
时刻注意单调性

浙公网安备 33010602011771号