zoukankan      html  css  js  c++  java
  • 牛牛的揠苗助长(二分)

    牛牛的揠苗助长

    题目链接

    思路

    我们考虑最小值的时候通常会考虑二分,但是这道题题目该如何二分呢。

    我们知道在时间为(t)的范围内我们能改变数组中(2t)个值,所以这道题目就是以时间为边界去二分,每当我们经过(t)个时间,显然数组中的某一些项会增加。这个时候对数组排一个序,中间的值将会是最优的,也就是(t)时间时,需要人为去变换值的基准,然后以这个为基准进行一趟变换,求得人为需要调动的次数,再跟(t)进行比较,如果(调动次数 <= t)这个时候说明可能存在更优解,更新二分边界(r = mid)

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 1e5 + 10;
    
    ll a[N], b[N];
    int n;
    
    bool judge(ll mid) {
        for(int i = 1; i <= n; i++) {
            b[i] = a[i] + mid / n;
            if(mid % n >= i)    b[i]++;
        }
        sort(b + 1, b + 1 + n);
        ll ans = b[n + 1 >> 1], sum = 0;
        for(int i = 1; i <= n; i++)
            sum += llabs(b[i] - ans);
        return sum <= mid;
    }
    
    int main() {
        // freopen("in.txt", "r", stdin);
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        ll l = 1, r = 1e18;
        while(l < r) {
            ll mid = l + r >> 1;
            if(judge(mid))  r = mid;
            else    l = mid + 1;
        }
        cout << l << endl;
        return 0;
    }
    
  • 相关阅读:
    动手动脑
    选课1.0
    四则运算
    JAVA异常处理机制资料整理
    JAVA学习日报(快乐作业) 10.27
    JAVA学习日报(快乐作业) 10.20
    JAVA学习日报 9/30
    JAVA学习日报 9/28
    JAVA学习日报 9/27
    JAVA学习日报 9/26
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12856076.html
Copyright © 2011-2022 走看看