Make It Equal

Make It Equal
There is a toy building consisting of nn towers. Each tower consists of several cubes standing on each other. The ii-th tower consists of hihi cubes, so it has height hihi.

Let’s define operation slice on some height HH as following: for each tower ii, if its height is greater than HH, then remove some top cubes to make tower’s height equal to HH. Cost of one “slice” equals to the total number of removed cubes from all towers.

Let’s name slice as good one if its cost is lower or equal to kk (k≥nk≥n).

Calculate the minimum number of good slices you have to do to make all towers have the same height. Of course, it is always possible to make it so.

Input
The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, n≤k≤109n≤k≤109) — the number of towers and the restriction on slices, respectively.

The second line contains nn space separated integers h1,h2,…,hnh1,h2,…,hn (1≤hi≤2⋅1051≤hi≤2⋅105) — the initial heights of towers.

Output
Print one integer — the minimum number of good slices you have to do to make all towers have the same heigth.

Examples
inputCopy
5 5
3 1 2 2 4
outputCopy
2
inputCopy
4 5
2 3 4 5
outputCopy
2
Note
In the first example it’s optimal to make 22 slices. The first slice is on height 22 (its cost is 33), and the second one is on height 11 (its cost is 44).

题目大意:在每次不超过m的代价,切割一层或者几层,代价等于切割该平面以上的所有正方体的个数。

新学了一种思想,网上说是差分,查了半天也模棱两可,举了个例子才知道说的是啥,但原理还是不知道 ,蒟蒻数学不好。。。
给一串数 如 1 2 3 4 5,给你几次操作 (两次为例),每次都给某个区间内的每个数改变x(加减乘除),例如1、 给 2到5之间的数都增加 1 。 2、给2到3之间的每个数都增加1。
怎么做能难道用两个for?例子简单但是如果给很长的一串数呢。
这时就可以使用该思想了:
加一个标记数组,b[1000];
每次给区间起始数字加1,终止数字后一个 -1;
也就是b[2]++,b[5 + 1]–;
这种操作完之后,我们可以得到的b数组为:b[0] = 0,b[1] = 0,b[2] = 2,b[3] = 0,b[4] = -1,b[5] = 0,b[6] = -1;
接下来怎么做?
我们可以使用一个for使每个b和他的前一位数求和:

for(int i = 1; i <= 6; i++) b[i] += b[i - 1];

这样得到的b数组为,b[0] = b[1] = 0,b[2] = 2,b[3] = 2,b[4] = 1,b[5] = 1,b[6] = 0;
很明显每个数改变的次数就求出来了,即2增加了2次1,3增加了2次1,4增加了1次 ,5增加了1次;
最后操作完的序列就可以求出来。

对于该题呢,我们可以把它当作一个全为0的数列 每次输入的高度相当于
从区间1到h都增加1。进行完操作之后,就可以求出来每层的块数,然后从最后一层一直找到高度最小的上一层。
代码:

#include<bits/stdc++.h>
using namespace std;
int h[200005];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int minx = 100000005;
    for(int i = 0; i < n; i++) {
        int hh;
        scanf("%d",&hh);
        minx = min(hh, minx);
        h[1]++, h[hh + 1] --;
    }
    for(int i = 1; i <=  200000;i++) h[i] += h[i - 1];
   // for(int i = 1; i <= 5; i++) cout << h[i] << endl;
    int temp = 0;
    int ans = 0;
    for(int i = 200000; i >= minx + 1; i--){
        temp += h[i];
        if(temp > m){ans++, temp = 0,i ++;}
    }
    if(temp) ans++;
    cout << ans << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值