1 solutions

  • 0
    @ 2025-5-16 14:57:50

    本题有贪心的做法,留给同学思考

    这里只介绍二分答案的做法。

    假如我们尝试发动midmid的次忍术,那么每种忍者最多提供 min(mid,a[i])min(mid, a[i]) 个人,在这种情况下我们最少需要 m×midm \times mid 个忍者。

    因此我们可以比较 i=1nmin(mid,a[i])\sum_{i = 1}^nmin(mid, a[i]) 是否大于等于 m×midm \times mid 来判定是否足够发动mm次忍术。

    有同学可能会问为啥 大于等于 m×midm \times mid 就一定可行 ? 考虑抽屉原理在midmid 个抽屉里,不存在相同类型的两个忍者,则一定可行。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    ll x[100005];
    
    int main() {
        ll n, m, ans = 0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> x[i];
        ll l = 0, r = 1e18;
    
        while (l <= r) {
            ll mid = (l + r) >> 1;
            ll sum = 0;
            for (int i = 1; i <= n; i++) {
                sum += min(x[i], mid);
            }
            // sum >= m * mid 等价于 sum / mid >= m, 防止乘法溢出
            if (sum / mid >= m) {
                l = mid + 1;
                ans = mid;
            } else {
                r = mid - 1;
            }
        }
        cout << ans;
        return 0;
    }
    

    Information

    ID
    665
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    9
    Tags
    (None)
    # Submissions
    42
    Accepted
    3
    Uploaded By