您的位置:首页 > 其它

CSU-ACM2017暑假集训2-二分搜索 F - Drying

2017-07-25 21:43 323 查看

F - Drying

It is very hard to wash and especially to dry clothes in winter. But Jane is a very smart girl. She is not afraid of this boring process. Jane has decided to use a radiator to make drying faster. But the radiator is small, so it can hold only one thing at a time.

Jane wants to perform drying in the minimal possible time. She asked you to write a program that will calculate the minimal time for a given set of clothes.

There are n clothes Jane has just washed. Each of them took ai water during washing. Every minute the amount of water contained in each thing decreases by one (of course, only if the thing is not completely dry yet). When amount of water contained becomes zero the cloth becomes dry and is ready to be packed.

Every minute Jane can select one thing to dry on the radiator. The radiator is very hot, so the amount of water in this thing decreases by k this minute (but not less than zero — if the thing contains less than k water, the resulting amount of water will be zero).

The task is to minimize the total time of drying by means of using the radiator effectively. The drying process ends when all the clothes are dry.

有n件衣服,每件衣服的含水量是ai,晾干的速度是每分钟含水量-1,烘干的速度是每分钟含水量-k,烘干和晾干的速度不叠加,即烘干时只按速度-k计算,不算-(k + 1);算出把这n件衣服弄干所需的最短时间。


Input

The first line contains a single integer n (1 ≤ n ≤ 100,000). The second line contains ai separated by spaces (1 ≤ ai ≤ 10^9). The third line contains k (1 ≤ k ≤ 10^9).


Output

Output a single integer — the minimal possible number of minutes required to dry all clothes.


Sample Input

sample input #1
3
2 3 9
5

sample input #2
3
2 3 6
5


Sample Output

sample output #1
3

sample output #2
2


直接枚举每件衣服十分复杂,不好做,采用二分枚举答案的方法较优。

显然,不使用烘干机,或烘干机烘干速度为-1时耗时最长,理论上最长时间数值上等于含水最多的那件衣服的含水量 aimax;又由题可知,每次计算必有潮湿的衣服存在,所以理论上最短时间就为1;分别以1和最大含水量 aimax 为下界和上界,对答案二分,再以此二分的结果枚举每件衣服,看是否满足这个答案。

从样例输入输出可以看出,若答案为 t ,我们可以认为含水量不大于 t 的衣服都是自然晾干的;含水量大于 t 的衣服都或多或少地经过了烘干。

由此可设含水量大于 t 的衣服中,每件衣服烘干用时 x1 , 晾晒用时 x2 , 含水量为 ai ;通过二分枚举出的答案为 mid , 这些衣服总的烘干用时为 sum

这些量满足以下关系:

mid=x1+x2 ai≤k∗x1+x2

整理得

x1≥ceil(ai−midk−1)

右边就是每件衣服的最短烘干时间。

由于烘干过程在同一时刻只能对一件衣服进行,是串行消耗时间的;晾干过程在同一时刻可以对多件衣服一起进行,是并行消耗时间的。所以只要将所有的最小 x1 相加得到 sum ,再将 summid 进行比较: sum > mid , 说明 mid 过小; sum < mid ,说明 mid 可以继续优化; sum == mid ,说明 mid 为所求。

另外还注意到第三个公式中有分母 k - 1 ,所以要对 k == 1 的情况单独进行处理。

#include <iostream>
#include <cstdio>
#include <math.h>
#include <vector>
using namespace std;
int main(){

long long n, k;
while(cin >> n){
vector<long long> myVec;
long long temp, maxTemp = 0;
for(long long i = 0; i < n; i++){
scanf("%lld", &temp);
myVec.push_back(temp);
maxTemp = temp > maxTemp ? temp : maxTemp;
}
cin >> k;
if(k == 1){
// k == 1 时用烘干机和不用烘干机没有区别,直接输出最长时间。

cout << maxTemp << endl;
continue;
}
long long l = 1, r = maxTemp, mid, ans;
while(l <= r){
mid = (l + r) / 2;
long long x = 0;
for(long long i = 0; i < myVec.size(); i++){
if(myVec[i] > mid){
x += (myVec[i] - mid + k - 2)/(k - 1);
//使用ceil()会得到Wrong Answer,所以采取这种向上取整的方法。

}
}
if(x > mid){//mid is too small.
l = mid + 1;
}
else{//mid is too big or just it.
ans = mid;
//获得正确的mid。
r = mid - 1;
}
}
cout << ans << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索 二分