斜率优化学习笔记
这是等了好久的笔记了。
斜率优化一直是我 OI 中的一个大坑,我刚接触它的时候是在 摆渡车 这题,看到斜率凸包啥的,那时候我才是六年级,十分的不理解,于是一直觉得它十分困难。
暑假终于迎来了转机,NLFS 讲 DP 优化那天顺便讲了下斜率优化,终于大悟,乃写此文章,供复习等用。
先来看一道题:
斜率优化的板子题
给你
斜率优化主要是推式子,我们来看如果有两个点
将式子代入可得
两边同时乘以
所以,总结如下:当
接着我就要谈大家最不耐烦也是最难听懂的部分,凸包,我尽量说的详细一些。
先来考虑最简单的三个点
此时显然可以发现
那么上凸壳呢?
此时
现在,我们对于每条直线找到它的最优决策点,首先要求得这些点的凸包,如果你不会请前往 【模板】二维凸包。
如图:
可以发现,当一条直线经过凸包上的一个点,且不碰到凸包,那么这个点就是这条直线的最优决策点,用眼瞪一下可得:
经过两点
也能得到
同理可得所有的点在
得到了这个结论后我们来看如何得到所有直线的最佳决策点。
1.离线做法
对于直线
进一步推广可知:对于两个直线
反过来一下得到斜率越大的直线决策点在越前面。
于是可以将斜率从大到小排序,每一轮取出当前斜率最大的直线放在后面的点上试答案(即看下能不能碰到凸包),如果不是最有决策点,那么对于后面斜率更小的直线,这个点也一定不是它的最优决策点。
剩下的直线决策点都是最后一个点了。
然后判断是否是最优答案其实只需要判这个点的答案是否比两边的答案都要大即可。
看一下代码吧:
#include <iostream> #include <algorithm> #define int long long using namespace std; int n, m, tp; int ans[100005]; pair <int, int> a[100005], tb[100005]; struct Line {int k;int id;}q[100005]; bool cmp (Line l1, Line l2) {return l1.k > l2.k;} int k (pair <int, int> p1, pair <int, int> p2) {return (p1.second - p2.second) / (p1.first - p2.first);} int fun (pair <int, int> p, int k) {return -p.first * k + p.second;} signed main () { cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> a[i].first >> a[i].second; sort (a + 1, a + n + 1); for (int i = 1; i <= n; i ++) { while (tp >= 2) { if ( (tb[tp].second - tb[tp - 1].second) * (a[i].first - tb[tp].first) <= (a[i].second - tb[tp].second) * (tb[tp].first - tb[tp - 1].first) ) tp --; else break; } tb[++ tp] = make_pair (a[i].first, a[i].second); } for (int i = 1; i <= m; i ++) { cin >> q[i].k; q[i].k = -q[i].k; q[i].id = i; } sort (q + 1, q + m + 1, cmp); int r = 1; for (int i = 1; i <= m; i ++) { if (r == tp) { ans[q[i].id] = fun (tb[r], q[i].k); continue; } while (r != tp && fun (tb[r], q[i].k) <= fun (tb[r + 1], q[i].k) ) ++ r; ans[q[i].id] = fun (tb[r], q[i].k); } for (int i = 1; i <= m; i ++) cout << ans[i] << "\n"; return 0; }
2.在线二分做法
其实大家有没有发现,若点
代码不补了。
例题二咕咕咕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异