E:Restorer Distance(三分)

Restorer Distance

思路

由于push和move这两个操做,咱们比较容易发现这两个操做好像在最大值最小值两头是等价的,所以当在最大最小值中间可能存在一个最优值,使操做成本最低。c++

经过上面的分析咱们能够大体的获得这是一个凹函数,而且存在最极小值,所以咱们能够考虑三分去的到这个最小值。函数

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 1e5 + 10;

int a[N], n, A, R, M;

ll f(int x) {
    ll sum1 = 0, sum2 = 0;//分别记录大于当前值的数量,和小于当前值的数量。
    for(int i = 1; i <= n; i++) {
        if(a[i] > x)    sum1 += a[i] - x;
        else if(a[i] < x)   sum2 += x - a[i];
    }
    ll ans = 0;
    ll mid = min(sum2, sum1);
    ans += mid * M;
    sum1 -= mid, sum2 -= mid;//优先考虑从一个移到另外一个上。
    if(sum1)    ans += sum1 * R;
    if(sum2)    ans += sum2 * A;
    return ans;
}

int main() {
    // freopen("in.txt", "r", stdin);
    scanf("%d %d %d %d", &n, &A, &R, &M);
    M = min(M, A + R);//这个操做能够等同是前两个操做的和,取一个最小值。
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    int l = 0, r = 1e9;
    while(l < r) {
        int lmid = l + (r - l) / 3;
        int rmid = r - (r - l) / 3;
        if(f(lmid) >= f(rmid))  l = lmid + 1;
        else    r = rmid - 1;
    }
    printf("%lld\n", min(f(l), f(r)));
    return 0;
}
相关文章
相关标签/搜索