題目鏈接:http://poj.org/problem?id=3104
這道題是我做的第一道二分枚舉答案的題吧,可是實(shí)際上做的也不怎么樣……
首先二分枚舉答案,也就是最短時(shí)間,如果a[i]<t的話直接讓它自然風(fēng)干就行,如果大于t就計(jì)算使用幾次風(fēng)干器,假設(shè)x1是自然風(fēng)干時(shí)間,x2是使用風(fēng)干器的次數(shù),那么x1+x2=t,x1+x2*k=a[i],兩個(gè)方程聯(lián)立,求出來使用的次數(shù)應(yīng)該是(a[i]-t)/(k-1)的上界,所以把所有的使用散熱器和自然風(fēng)干的時(shí)間加到一起,和枚舉的答案比較,然后繼續(xù)二分就行。

view code
1 #include <cstdio>
2 #include <cmath>
3 int maxt, t, a[100100], k, n;
4 bool check(int tt){
5 double rt = 0;
6 for (int i = 0; i < n; i++)
7 if (a[i] > tt) rt += ceil(double(a[i] - tt) / double(k - 1));
8 if (rt <= tt) return 1;
9 else return 0;
10 }
11 void solve(){
12 int l = 0, r = maxt;
13 while (l <= r){
14 int m = (l + r) >> 1;
15 if (check(m)){
16 if (!check(m - 1)){
17 t = m; return;
18 }
19 r = m - 1;
20 }
21 else l = m + 1;
22 }
23 }
24 int main(){
25 while (~scanf("%d", &n)){
26 maxt = 0;
27 for (int i = 0; i < n; i++){
28 scanf("%d", &a[i]);
29 if (a[i] > maxt) maxt = a[i];
30 }
31 scanf("%d", &k);
32 solve();
33 printf("%d\n", t);
34 }
35 return 0;
36