斜率优化
斜率优化其实是一种思想,在 dp 的时候我们可能会遇到一类问题,这类问题依赖于之前的状态转移。因此多了一重枚举前一个元素的复杂度。而斜率优化是通过对一类特殊的最优化问题,尝试用决策点关于斜率的式子去除一些无用的决策,从而优化时间复杂度。
下面将给出几道习题来理解该算法。
[SDOI2016] 征途
Statement
求
Analysis
展开上式
注意到
有个非常朴素的 dp:设
我们发现
时间复杂度
记
尝试进行优化,考虑对于两个决策点
假设
像这种可以将不等式拆成两点之间斜率和一条已知斜率直线进行比较的式子可以使用斜率优化。
接下来考虑斜率优化的工作流程(图来源于 oi-wiki)
考虑我们的决策必须经过某个点,而直线的斜率已经固定,因此可以用这根直线去切某个下凸包上的点。显然,相切这个点最优。一个点要能与这跟直线相切,满足 与前一个点的连线斜率 小于 已知直线的斜率,与后一个点的连线斜率 大于 已知直线的斜率。由于在凸包上,斜率是单调递增的,因此可以用单调队列维护。
这里给出单调队列部分代码。
for (int j = 1; j <= m; ++j) {
cur ^= 1;
memset(f[cur], 0, sizeof cur);
int l = 1, r = 0;
q[++r] = 0;
for (int i = 1; i <= n; ++i) {
while (l < r && slope(q[l + 1], q[l]) < 2 * s[i]) ++l;
f[cur][i] = f[cur ^ 1][q[l]] + sqr(s[i] - s[q[l]]);
while (l < r && slope(q[r], q[r - 1]) > slope(q[r], i)) --r;
q[++r] = i;
}
}
[NOI2019] 回家路线
笔者调了一天愣是没发现自己哪里写错了于是愤然重构代码居然一遍过,以下内容是笔者在精神不太正常的时候写下的。
听说这道题还有
考虑朴素 dp,假设
在考虑到由于站点的转移限制,远跑不满 虽然可以构造数据卡掉但是好像没造?
暴力拆开式子移项:
因为
假设现在有两点
标准式子,维护单调队列即可。
因为笔者根本不想调代码,因此不贴代码了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探