斜率优化
Posted wscqwq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了斜率优化相关的知识,希望对你有一定的参考价值。
重点讲讲斜率优化的套路。
首先需要将式子化为 \\(y=kx+b\\) 的形式,其中 \\(y,x\\) 为一个关于变量 \\(j\\) 的式子,\\(k\\) 为一个关于常量 \\(i,b\\) 的式子。然后根据 \\(x,k\\) 的单调性考虑是二分还是直接单调。注意如果求最小值是下凸包,最大值是上凸包(最小值是直线从下面往上靠,最大值反之),然后如果删除队首不合法的,最小值和最大值也要反着来。可以自己用一个坐标轴上画一些点,用一条直线来靠就能回忆起来。
模板斜率优化dp
题目链接:https://codeforces.com/problemset/problem/1083/E
本来是想写计几的,结果发现是到斜率优化dp,正好也没怎么做过斜率dp,整理一下板子。
感觉斜率优化dp就和凸包差不多,维护一个上(下)凸包的亚子。
1 // f[j] = yi * xj + wi - xi * yi + fi; 2 //维护上凸包,斜率递减 3 #include<bits/stdc++.h> 4 using namespace std; 5 typedef long long ll; 6 const int N = 1e6 + 9; 7 struct Point{ 8 ll x,y,w; 9 bool operator < (const Point& b)const{ 10 return x < b.x; 11 } 12 }a[N]; 13 ll q[N],f[N]; 14 double cal(int i,int j){ 15 return 1.0 * (f[j] - f[i]) / (a[j].x - a[i].x); 16 } 17 int main(){ 18 int n; scanf("%d",&n); 19 for(int i =1;i<=n;++i) scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].w); 20 sort(a+1,a+1+n); 21 int l = 1, r = 1; 22 ll ans = -1000000000000000; 23 for(int i = 1;i<=n;++i){ 24 while( l < r && cal(q[l],q[l+1]) >= a[i].y ) ++l; 25 int j = q[l]; 26 f[i] = f[j] - a[i].y * a[j].x - a[i].w + a[i].x * a[i].y; 27 ans = max(ans,f[i]); 28 while( l < r && cal(q[r-1],q[r]) <= cal(q[r],i) ) --r; 29 q[++r] = i; 30 } 31 printf("%lld",ans); 32 }
以上是关于斜率优化的主要内容,如果未能解决你的问题,请参考以下文章