【题意】:给出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