• 【模板变形】凸壳二分+斜率优化dp——cf1083E


    由于斜率不是递增的,所以凸壳队列的head就不能动(退化成了一个单调栈),然后每次二分找直线切到的点

    #include<bits/stdc++.h>
    using namespace std;
    #define N 2000006
    #define ll long long 
    
    struct point{
        ll x,y;
        point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
        point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    };
    ll cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    double slope(point k1,point k2){return 1.0*(k1.y-k2.y)/(k1.x-k2.x);}
    point q[N]; 
    int head,tail;
    ll find(ll k){//凸壳上最右边的斜率>=k的点
        if(tail==1)return 1; 
        ll L=2,R=tail,mid,ans=1;
        while(L<=R){
            mid=L+R>>1;
            if(slope(q[mid],q[mid-1])>=k)    
                L=mid+1,ans=mid;
            else R=mid-1;
        }
        return ans;
    }
    void push(point k){//维护一个上凸壳 
        while(tail>1 && slope(q[tail],q[tail-1])<=slope(k,q[tail-1]))
            tail--;
        q[++tail]=k; 
    } 
    
    struct Node{ll x,y,a;}p[N];
    int cmp(Node a,Node b){
        if(a.x==b.x)return a.y<b.y;
        return a.x<b.x;
    }
    ll n,dp[N];
    
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++)
            scanf("%lld%lld%lld",&p[i].x,&p[i].y,&p[i].a);
        sort(p+1,p+1+n,cmp);
        
        head=tail=1;
        q[1]=(point){0,0};
        ll ans=0;
        for(int i=1;i<=n;i++){
            ll pos=find(p[i].y);//寻找上凸壳里的点
            dp[i]=q[pos].y-q[pos].x*p[i].y-p[i].a+p[i].x*p[i].y; 
            push((point){p[i].x,dp[i]});
            ans=max(ans,dp[i]);
        }
        cout<<ans<<'
    ';
    } 
  • 相关阅读:
    jekyll简单使用
    三、ansible简要使用
    四、ansible主机组定义
    项目中远程连接404 NOT FOUND问题的原因以及解决办法(这里只涉及我遇到的问题)
    AS3中的位操作
    AS3中is和as操作符的区别
    static 函数和普通函数的区别
    [译] SystemTap
    2017-09-17 python 学习笔记
    xargs 命令使用小记
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12521332.html
Copyright © 2020-2023  润新知