poj3104Drying【二分】
大意:
有n件刚洗的衣服 每件衣服现在的含水量位a[i]
现在想要把衣服弄干
每件衣服自然风干含水量每分钟减少1
如果用暖气片烤干每分钟减少k
问 最少多长时间能够把所有的衣服弄干
分析:
这个题一开始我以为是个贪心 贪心的方法是 每次选择含水量最大的衣服来烤 然后求得结果 提交一次wa
然后从discuss中看到了二分的思路
这个思路非常好
我们二分弄干的时间 t
那么对于含水量 <= t 的那些衣服 不用管它们 让它们自然风干就好了
对于含水量 >t 的那些衣服 假如说其含水量为 a[i]
设 x为烘烤该件衣服的时间 y为风干的时间
那么
x + y = t
x * k + y >= a[i]
整理得
x >= (a[i] - t) / ( k - 1)
这样对于每件衣服 我们都可以求得用这么长的时间最少的烘干所用的时间
求出总和与二分结果比较
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 100005; 9 int a[maxn]; 10 int n, k; 11 12 bool cmp(int a, int b) { 13 return a > b; 14 } 15 16 bool check(int mid) { 17 long long sum = 0; 18 for(int i = 1; i <= n; i++) { 19 if(a[i] <= mid) break; 20 sum += (long long) ( ( a[i] - mid ) / ( k - 1) ); 21 if( (a[i] - mid) % (k - 1) != 0 ) { 22 sum++; 23 } 24 } 25 if(sum <= mid) return true; 26 return false; 27 } 28 29 int main() { 30 while(EOF != scanf("%d",&n) ) { 31 for(int i = 1; i <= n; i++) { 32 scanf("%d",&a[i]); 33 } 34 sort(a + 1, a + n + 1, cmp); 35 scanf("%d",&k); 36 if(k == 1) { 37 printf("%d\n", a[1]); 38 continue; 39 } 40 int low = 0, high = 1000000000; 41 while(low <= high) { 42 int mid = (low + high) >> 1; 43 if(check(mid) ) { 44 high = mid - 1; 45 } else { 46 low = mid + 1; 47 } 48 } 49 printf("%d\n", high + 1); 50 } 51 return 0; 52 }