简介:
- 在
dp
d
p
的转移方程中, 对不必要的状态量进行抛弃,对不优的状态量进行搁置,使得在常数时间内找到最优解成为可能。
- 斜率优化依靠的是数形结合的思想,通过将每个阶段和状态的答案反映在坐标系上寻找解答的单调性,来在一个单调的答案(下标)队列中O(1)得到最优解。
- 斜率优化
dp
d
p
其实是单调队列的推广,单调队列、旋转卡壳、斜率优化都利用了单调性降低时间复杂度。
分析:
- 形如
dp
d
p
转移方程:
dp[i]=min/max
d
p
[
i
]
=
m
i
n
/
m
a
x
{
dp[j]+g[j]∗x[i]+M
d
p
[
j
]
+
g
[
j
]
∗
x
[
i
]
+
M
}
- 对于这一类转移我们可以化成
k∗x+y
k
∗
x
+
y
最值的问题我们可以通过凸包的制造是最优解满足单调性质(当k有序是此时我们用到的节点以后一定不会用到)
- 对于求
min
m
i
n
的
dp
d
p
,一般最后的不等式化简得到
dydx<k
d
y
d
x
<
k
,那么应该用下凸包。
- 同理,对于求
max
m
a
x
的
dp
d
p
,一般最后的不等式化简得到
dydx>k
d
y
d
x
>
k
,那么应该用上凸包。
模板(code):
LL getY(int p1,int p2){
return dp[p2]-dp[p1];
}
LL getX(int p1,int p2){
return g[p2]-g[p1];
}
LL getDP(int p1,int p2){
return dp[p2]+g[p2]*x[p1]+M;
}
int main(){
read();
L=R=0;
Q[R++]=0;
REP(i,1,n){
while(L+1<R && getY(Q[L],Q[L+1])<=-x[i]*getX(Q[L],Q[L+1]))L++;
dp[i]=getDP(i,Q[L]);
while(L+1<R && getY(Q[R-1],i)*getX(Q[R-2],Q[R-1])<=getY(Q[R-2],Q[R-1])*getX(Q[R-1],i))R--;
Q[R++]=i;
}
put();
return 0;
}
总结:
- 首先要满足斜率优化的条件吧…那么可以将
O(n)−>O(logn)
O
(
n
)
−
>
O
(
l
o
g
n
)
- 在凸包的问题中,会遇到一些不满足单调的情况,那么就要三分或二分去找最优解了。