1 条题解

  • 1
    @ 2022-8-6 15:42:09

    为简便,以下 (w,l)(x,y)(w,l)\rightarrow(x,y)

    首先如果 (x1,y1)(x_1,y_1)(x2,y2)(x_2,y_2) 满足 x1x2,y1y2x_1\le x_2,y_1\le y_2,则 (x1,y1)(x_1,y_1)(x2,y2)(x_2,y_2) 合购更优,因此忽略这样的 (x1,y1)(x_1,y_1)

    于是直接考虑剩下的 (x2,y2)(x_2,y_2) 会构成怎样的平面上的点集。

    显然 xx 单调增时 yy 单调减。

    这个东西可以拿个单调栈求出。

    剩下的点按 xx 升序排列。

    然后可以发现剩下的分组必然各自得是连续的一段,否则不优。

    fnf_n 表示第 nn 个点是某个分组的结尾时的最小花费。

    fn=min{yk+1xn+fk0k<n}f_n=\min\{y_{k+1}x_n+f_k|0\le k<n\}

    稳妥妥的斜率优化。

    直接做就好了。


    说起来这个是否满足四边形不等式(交叉小于包含)啊?

    w(l,r)=ylxrw(l,r)=y_lx_r w(a,c)+w(b,d)w(a,d)+w(b,c)w(a,c)+w(b,d)\le w(a,d)+w(b,c)

    p.s. 用排序不等式可证。

    所以也可以半在线的决策单调性优化 dp。

    但我不会。/kk/kk/kk


    Code

    #include <algorithm>
    #include <deque>
    #include <stdio.h>
    #include <vector>
    typedef long long llt;
    typedef unsigned uint;typedef unsigned long long ullt;
    typedef bool bol;typedef char chr;typedef void voi;
    typedef double dbl;
    template<typename T>bol _max(T&a,T b){return(a<b)?a=b,true:false;}
    template<typename T>bol _min(T&a,T b){return(b<a)?a=b,true:false;}
    template<typename T>T lowbit(T n){return n&-n;}
    template<typename T>T gcd(T a,T b){return b?gcd(b,a%b):a;}
    template<typename T>T lcm(T a,T b){return(a!=0||b!=0)?a/gcd(a,b)*b:(T)0;}
    template<typename T>T exgcd(T a,T b,T&x,T&y){if(b!=0){T ans=exgcd(b,a%b,y,x);y-=a/b*x;return ans;}else return y=0,x=1,a;}
    template<typename T>T power(T base,T index,T mod)
    {
        T ans=1%mod;
        while(index)
        {
            if(index&1)ans=ans*base%mod;
            base=base*base%mod,index>>=1;
        }
        return ans;
    }
    int main()
    {
    #ifdef MYEE
        freopen("QAQ.in","r",stdin);
        // freopen("QAQ.out","w",stdout);
    #endif
        typedef std::pair<uint,uint>Pair;
        typedef std::pair<ullt,ullt>Pair2;
        uint n;scanf("%u",&n);std::vector<Pair>V(n);
        for(auto&v:V)scanf("%u%u",&v.first,&v.second);
        std::sort(V.begin(),V.end());
        {
            std::vector<Pair>Keep;
            for(auto v:V)
            {
                while(Keep.size()&&Keep.back().second<=v.second)Keep.pop_back();
                Keep.push_back(v);
            }
            V=Keep;
        }
        {
            std::deque<Pair2>Keep;
            auto val=[](Pair2 p,ullt x){return p.first*x+p.second;};
            ullt ans=0;
            for(auto v:V)
            {
                Pair2 line(v.second,ans);
                while(Keep.size()>=2)
                {
                    Pair2 line1=Keep.back(),line2=Keep[Keep.size()-2];
                    if((line.second-line2.second)*(line2.first-line1.first)<=
                        (line1.second-line2.second)*(line2.first-line.first))
                        Keep.pop_back();
                    else break;
                }
                Keep.push_back(line);
                while(Keep.size()>1&&val(Keep[0],v.first)>=val(Keep[1],v.first))Keep.pop_front();
                ans=val(Keep[0],v.first);
            }
            printf("%llu\n",ans);
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1597
    时间
    1000ms
    内存
    162MiB
    难度
    4
    标签
    (无)
    递交数
    48
    已通过
    24
    上传者