Educational Codeforces Round #52 C. Make It Equal

http://codeforces.com/contest/1065/problem/C

晚上状态比较奇怪,因为一些非常蠢的错误 wa 了好几次。

问题

\(N\) 个积木搭成的塔,这些塔的高度计为 \(H_i\),表示它是由 \(H_i\) 块积木搭成的。每次你可以指定一个高度 \(h\),把那些高度大于 \(h\) 的塔多出来的那一部分移除,代价为移除的积木数量。现在要求对这些积木进行若干次移除操作使所有塔最后的高度相同,问每次的操作代价不超过 \(K\) 的情况下,最少要进行几次操作。

题解

容易发现最后所有塔的高度应该是高度最小的塔的高度,只需要枚举 \(h\) 从上向下贪心地移除就好了。复杂度 \(O(N)\)

#include <bits/stdc++.h>

#ifdef LOCAL
    #define debug(...) fprintf(stderr, __VA_ARGS__)
#else
    #define debug(...) 0
#endif

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;

int rint() {
    int n, c, sgn = 0;
    while ((c = getchar()) < '-');
    if (c == '-') n = 0, sgn = 1;
    else n = c - '0';
    while ((c = getchar()) >= '0') {
        n = 10 * n + c - '0';
    }
    return sgn ? -n : n;
}

const int N = 200010;

int n, K;
int hei[N];
int cnt[N];

int main() {
    scanf("%d %d", &n, &K);
    int mi = N, ma = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d", &hei[i]);
        cnt[hei[i]]++;
        mi = min(mi, hei[i]);
        ma = max(ma, hei[i]);
    }

    int ans = 0;
    ll last = 0;
    int cumu = 0;
    for (int h = ma; h > mi; h--) {
        // next
        if (last + cumu + cnt[h] <= K) {
            last += cumu + cnt[h];
            cumu += cnt[h];
            continue;
        }
        // must
        ans++;
        last = cumu + cnt[h];
        cumu += cnt[h];
    }
    if (last > 0) ans++;
    printf("%d\n", ans);
    return 0;
}

总结

以后打代码前还是得先想好具体的细节。

猜你喜欢

转载自www.cnblogs.com/hfccccccccccccc/p/9777390.html