【题意】:给出n件刚洗完的衣服,每件衣服有一个属性ai,表示改衣服在自然风干的条件需要ti分钟。现在有一台烘干机,每分钟你可以选择把任意一件衣服放进去,那么这件衣服风干的时间就减少k分钟,而每分钟对于不在烘干机的衣服,风干时间都减少1。问最少用多少时间使所有衣服都干了。

【题解】:直接二分答案,然后判断答案的正确性。
               假设当前二分的答案为 t,那么:
               对于ai <= t的衣服,显然让它们自然风干就可以了。
               对于ai > t的衣服,我们需要知道该衣服最少用多少次烘干机。
               设该衣服用了x1分钟风干,用了x2分钟烘干机。
               那么有 x1 + x2 = t 和 ai <= x1 + x2 * k,联立两式可得 x2 >= (ai - t) / (k - 1),即最少使用次数为[(ai - t) / (k - 1)] 的最小上界。
               最后,判断一下总使用次数是否少于 t 即可。

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define lc(x) (x << 1)
15 #define rc(x) (x << 1 | 1)
16 #define lowbit(x) (x & (-x))
17 #define ll long long
18 #define maxn 100050
19 int n;
20 ll val[maxn], ans, k;
21 
22 bool check(ll t) {
23     ll cnt = 0;
24     for(int i = 0; i < n; i++) {
25         if(val[i] > t) {
26             cnt += (val[i] - t + k - 2) / (k - 1);
27             if(cnt > t) return false;
28         }
29     }
30     return true;
31 }
32 
33 void solve() {
34     ll l = 1, r = ans;
35     while(l <= r) {
36         ll mid = (l + r) >> 1;
37         if(check(mid)) ans = mid, r = mid - 1;
38         else l = mid + 1;
39     }
40     printf("%lld\n", ans);
41 }
42 
43 int main() {
44     while(~scanf("%d", &n)) {
45         ans = 0;
46         for(int i = 0; i < n; i++) {
47             scanf("%lld", &val[i]);
48             ans = max(ans, val[i]);
49         }
50         scanf("%lld", &k);
51         if(k == 1) printf("%lld\n", ans);
52         else solve();
53     }
54     return 0;
55 }
56