「斜率优化」学习笔记

当动态规划的状态数为\(O(n)\),每个状态的转移数也是\(O(n)\)时,称这种动态规划为1D1D动态规划。

对于这种问题,朴素做法是\(O(n^2)\)的。优化方法有不少。

斜率优化

首先证明决策单调性,即带入\(k<j\)进行比较。若式子能够化为斜率的形式,则可以使用斜率优化。

通过斜率我们可以得出每一个状态对应的点,利用决策单调性可以证明出上凸(或下凸)一定不优,由此问题转化为维护下凸(或上凸)。转移点一定是当前斜率对应的凸包顶点。用栈+二分实现即可。

在代码实现上有一些坑

斜率:

inline double slope(int i, int j){
    return (Y(i)-Y(j)) * 1.0 / ((X(i)==X(j)) ? -(1e-9) : (X(i)-X(j)));
}
sta[++top] = 0;
for(int i = 1; i <= n; ++i){
    p = top;
    l = 1, r = top-1;
    while(l <= r){
        mid = (l+r)>>1;
        if(slope(sta[mid],sta[mid+1]) > a[i]){
            p = mid;
            r = mid-1;
        }else{
            l = mid+1;
        }
    }
    int j = sta[p];
    ans = max(ans,org-a[i]*i+a[i]+a[i]*j+s[i-1]-s[j]);
    while(top > 1 && slope(sta[top],i) < slope(sta[top-1],sta[top])) --top;
    sta[++top] = i;
}

转载于:https://www.cnblogs.com/qixingzhi/p/11270340.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值