思维 || Make It Equal

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

题意:给你n个高度分别为a[i]的塔,每次可以横着切一刀,切掉不多于k个塔,问最少切多少刀才能把塔切的都一样高(k>=n)

高度和n都在2*10^5以内

思路:既然高度在20w以内嘛 那就按高度模拟惹 然鹅该怎么模拟着实头疼了一下下

用a[i] 记录高度为i-1时,有多少个塔有高度,如果当前高度为i-1时有a[i]个塔,并且a[i]<k,那么可以去考虑下一层

用sum记录上一层之前还有多少没切,比较sum+a[i]和k的大小可以决定切不切,切的话就cnt++,剩的sum就是a[i](因为是sum+a[i]>k时切的

然后就是a[i]怎么算出来的问题了嘤嘤嘤

用了桶排序(?)和前缀和(?)类似的思想(?)←开始瞎bb

因为越往高,塔数肯定不减,输入每个高度的时候记录一下到这个高度时,塔数要-1(a[h]--), 然后a[0]=n, a[i] += a[i-1],一个个往后加就可以了

#include <stack>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 200010;
const int INF = 1000000100;
int a[maxn];
int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    int maxh = 0;
    for(int i = 1; i <= n; i++)
    {
        int h;
        scanf("%d", &h);
        maxh = max(h, maxh);
        a[h]--;
    }
    a[0] = n;
    for(int i = 0; i <= maxh; i++)
        a[i] += a[i-1];
    int cnt = 0, res = 0;
    for(int i = maxh; i >= 0; i--)
    {
        if(a[i] == n)
        {
            if(res) cnt++;
            break;
        }
        if(res + a[i] > k)
        {
            cnt++;
            res = a[i];
        }
        else
            res += a[i];
    }
    printf("%d\n", cnt);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/pinkglightning/p/9780885.html