Luogu_P10977(AcWing_299) Cut the Sequence 题解
解题思路
考虑线性 dp。
首先如果存在 \(a_i>m\),那肯定不满足条件,输出 \(-1\)。
设 \(f_i\) 表示前 \(i\) 个数分成若干段,然后每段最大数之和,其中每段内的整数之和不超过 \(m\)。
\(f_i\) 肯定是由 \(f_j\)(\(1\le j<i\))转移过来的,也就是前 \(j\) 个数分好后再加上 \((j,i]\) 这一段,所以 \((j,i]\) 这一段需要满足 \(\sum\limits_{k=j+1}^{i}a_k\le m\),所以 \(j\) 就可以从 \(i-1\) 到 \(1\) 倒序枚举。
继而有转移方程:
\[f_i=\min_{j=1}^{i-1}\left\{\left[\sum_{k=j+1}^ia_k\le m\right]\times\max_{k=j+1}^i\left\{a_k\right\}\right\}
\]
时间复杂度为 \(\mathcal{O}(n^2)\),得分 \(24\text{pts}\)。
代码:
接着讲正解,单调队列优化 dp。
区间和可以用前缀和处理。
注意到 \(j\) 最小的时候满足 \(\sum\limits_{k=j+1}^ia_k\le m\),也就是说 \(\sum\limits_{k=j}^ia_k>m\),这个数可以单独处理,而 \(t=\max\limits_{k=j+1}^i\left\{a_k\right\}\) 可以通过单调队列存一个单调递减的最大值数列,但因为最后答案 \(f_j+t\) 不具有单调性,所以需要再存一个小根堆,建议用 multiset
,因为每次删除时优先队列不好删除。
时间复杂度为 \(\mathcal{O}(n\log_2n)\)。
AC 代码,请勿抄袭
__EOF__

本文作者:cyf1208
本文链接:https://www.cnblogs.com/cyf1208/p/18432002.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/cyf1208/p/18432002.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!