题目描述
冬天很难洗,尤其是干衣服。但简是一个非常聪明的女孩。她不怕这个无聊的过程。 Jane 决定使用散热器来加快干燥速度。但是散热器很小,所以一次只能装一件东西。
Jane 希望在尽可能短的时间内完成干燥。她让你编写一个程序来计算给定一套衣服的最短时间。
简刚洗了n件衣服。他们每个人在洗涤过程中都服用了 ai 水。每分钟,每件物品中所含的水量减少一(当然,前提是物品尚未完全干燥)。当含水量变为零时,布变干并准备好包装。
每一分钟,Jane 都可以选择一件东西在散热器上晾干。散热器很热,所以这个东西中的水量在这一分钟内减少了 k(但不小于零——如果这个东西含有少于 k 个水,那么产生的水量将为零)。
任务是通过有效地使用散热器来最小化干燥的总时间。当所有衣服都干燥时,烘干过程结束。
输入
第一行包含一个整数 n (1 ≤ n ≤ 100 000)。第二行包含由空格分隔的 ai (1 ≤ ai ≤ 109)。第三行包含 k (1 ≤ k ≤ 109)。
输出
输出一个整数——烘干所有衣服所需的最小可能分钟数。
样本输入1
3 2 3 9 5
样本输出1
3
样本输入2
3 2 3 6 5
样本输出2
2
思路分析
使用二分枚举晒干衣服的总时间(晾干+晒干) 最长时间就是最大的采用晾干的方法.最短时间可以假定为1.然后进行枚举mid.
假设衣服a[i] > mid; 择有 a[i] = k*t + mid -t ==> t =( a[i]-mid )/(k-1); 我们处理时,只需要判断这些a[i] > mid的衣服用的烘干机时间的总和有没有超过mid,如果超过了,那肯定是不满足的.
并且当k=1时需要特殊处理, 这时候,无论使用烘干机还是晾干,最后花费时间始终等于最大湿度的衣服.
需要注意:t的结果需要向上取整,因为你的余数再用一次烘干机最多才多1个时间,但是如果选择风干,就是至少1个时间.
AC代码:
#include<iostream> #include<math.h> #include<algorithm> using namespace std; const int maxsize=100000+5; int arr[maxsize],n,k,ans; int judge(int x){ int sum1 = 0;//烘干机使用时间 for(int i = 0;i < n;i++){ if(arr[i]>x){ sum1 += ceil((arr[i]-x)*1.0 / (k-1) );// 或sum += (a[i] - x + k -2) / (k-1); } if(sum1>x){ return 0; } } return 1; } void solve(){ int l = 1,r = arr[n-1]; while(l<=r){ int mid = (l + r)/2; if(judge(mid)){ r = mid-1; // 如果是mid-1则用一个ans保存最后的值. 如果是mid则最后输出mid即可.条件也变为right-left>1 ans = mid; }else{ l = mid+1; } } } int main(){ cin>>n; for(int i = 0;i < n;i++){ cin>>arr[i]; } cin>>k; sort(arr,arr+n);//进行排序 if(k==1){//如果烘干机的速度和自动晾干速度相同,那么 需要的时间==湿度最大衣服花费的时间. cout<<arr[n-1]<<endl; return 0; } solve(); cout<<ans<<endl; return 0; }