zoukankan      html  css  js  c++  java
  • Restorer Distance

    题意:

    有一行砖,每行的高度为:(h_i),有三种操作:
    1.使一堆的高度 (+1),花费:(A)
    2.使一堆的高度 (-1),花费:(R)
    3.把一堆的转移动到另一堆上面,花费:(M)
    求最小的花费,使得最终所有的砖一样高。

    分析:

    答案为单峰函数,利用三分求解。
    对最终的高度进行三分,求出当前高度下,需要的花费。注意,当增加和减少操作均有时,可以考虑和交换操作替代。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1e5+5;
    int h[N];
    int n,a,r,m;
    ll check(ll num)//最终的值
    {//cout<<"num="<<num<<endl;
        ll cnt1=0,cnt2=0;
        for(int i=1;i<=n;i++)
        {
            if(h[i]>num) cnt1+=(h[i]-num);
            else if(h[i]<num) cnt2+=(num-h[i]);
        }
        ll t=min(cnt1,cnt2);
        ll res=cnt1*r+cnt2*a;
        ll te=r*(cnt1-t)+a*(cnt2-t)+m*t;
        //cout<<min(res,te)<<endl;
        return min(res,te);
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&a,&r,&m);
        ll l=1e10,r=-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&h[i]);
            l=min(l,1LL*h[i]);
            r=max(r,1LL*h[i]);
        }
        while(l+5<=r)
        {
            ll mid1=(l+r)>>1;
            ll mid2=(mid1+r)>>1;
            if(check(mid1)<=check(mid2))
                r=mid2-1;
            else
                l=mid1+1;
        }
        ll ans=1e18;
        for(ll i=l;i<=r;i++)
            ans=min(ans,check(i));
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (二) —— SQLite
    理解 Continuation
    99种用Racket说I love you的方式
    Racket Cheat Sheet
    scheme 教程 #lang racket
    开始学习Scheme
    MIT Scheme 的基本使用
    CPS变换
    SECD machine
    scheme 之门
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12926595.html
Copyright © 2011-2022 走看看