西北大学校赛B题 北境之都 【三分】

传送门

题意: 给定n座房子的高度, 要求任意两座房子的高度差在m以内, 每个房子只能改变一次高度,将一个房子的高度改变k米的花费是k^2万元,求最低要花费多少万元

思路: 很明显, 将一个房子的高度放在过高或者过低的都是不最优, 而是中间的某个值, 比如样例就是45, 所以我们可以三分一下最低高度x, 然后x + m作为最高高度, 比x小的变为x, 比x+m 大的变为 x + m, 然后取最优值即可.

AC Code

int a[maxn];
int n, m;
ll f(int x) {
    ll tot = 0;
    for (int i = 1 ; i <= n ; ++ i) {
        if (a[i] < x) tot += 1ll * (x - a[i]) * (x - a[i]);
        if (a[i] > x + m)
            tot += 1ll * (a[i] - x - m) * (a[i] - x - m);
    }
    return tot;
}
void solve() {
    scanf("%d%d", &n, &m);
    int l = inf, r = - inf;
    for (int i = 1 ; i <= n ; ++ i) {
        scanf("%d", a+i);
        l = min(l, a[i]);
        r = max(r, a[i]);
    }
    ll ans = 0;
    while(l <= r) {
        int len = (r - l) / 3;
        int lm = l + len, rm = r - len;
        ll flm = f(lm), frm = f(rm);
        if (flm >= frm) {
            ans = flm;
            l = lm + 1;
        }
        else {
            ans = frm;
            r = rm - 1;
        }
    }
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值