背景
每件衣服都有一定单位水分,在不适用烘干器的情况下,每件衣服每分钟自然流失1个单位水分,但如果使用了烘干机则每分钟流失K个单位水分,但是遗憾是只有1台烘干机,每台烘干机同时只能烘干1件衣服,请问要想烘干N件衣服最少需要多长时间?
输入
第一行输入N,表示有N件衣服,第二行输入N件衣服的水分ai,第三行表示烘干机每分钟烘干水分K
其中
1 ≤ N ≤ 100 000,1 ≤ ai ≤ 10^9,1 ≤ K≤ 10^9输出
输出烘干N件衣服所需要的最短时间
样例输入
3 2 3 9 5 3 2 3 6 5
样例输出
3 2
解题思路:当看到这题我们可以发现如果你要烘干n件衣服,那么另外一半的衣服刚好能全部干是最好的,所以由此可以想到二分
代码 (此题用的是 r = mid, l = mid+1做)
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <string> #include <cmath> #include <vector> #include <stack> #include <queue> #include <stack> #include <list> #include <map> #include <set> //#include <unordered_map> #define Fbo friend bool operator < (node a, node b) #define mem(a, b) memset(a, b, sizeof(a)) #define FOR(a, b, c) for(int a = b; a <= c; a++) #define RFOR(a,b, c) for(int a = b; a >= c; a--) #define sc(a) scanf("%lld",&a) #define off ios::sync_with_stdio(0) bool check1(int a) { return (a & (a - 1)) == 0 ? true : false; } using namespace std; typedef pair<int, int> pii; typedef long long ll; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const int Maxn = 2e5 + 5; const double pi = acos(-1.0); const double eps = 1e-8; ll a[Maxn];//水分 ll n;//衣服件数 ll k;//烘干机一次烘干的水分 int solve(ll mid) { //假设目前用mid的时间烘干衣服 /*如果一件衣服a[i]小于mid,可自然风干,否则需要用机器,那么只要判断在mid时是否需要使用机器就可以 但是如果一件衣服 自然风干的时候用时t1 用机器烘干t2 (1)t1+t2 = mid (2)t1+k*t2 >= a[i] 联立两个方程解得 t2 <= mid-a[i]/(1-k) */ ll cnt = 0; FOR(i, 1, n) { if (a[i] > mid) { //如果一件衣服要使用机器 cnt += (ll)ceil((double)(a[i]-mid*1.0)/(k - 1));//算出要烘干的次数, k==0的时候无意义 } } if (cnt <= mid) //有多余的时间 return 1; else return 0; } int main() { sc(n); FOR(i, 1, n) sc(a[i]); sc(k); sort(a + 1, a + 1 + n); if (k == 1) { //特判 printf("%lld\n", a[n]); return 0; } ll l = 1, r = a[n]; while (l < r) {//解释一下为什么l<r : 当需要增大时间时候l = mid+1,不需要时间时候r = mid //那么当 l==r 的时候就会跳出循环输出l即可 ll mid = (l + r) >> 1; if (solve(mid)) { //如果当前用mid的时间来烘干衣服有多余的时间 r = mid; } else l = mid+1;//时间少了,需要增大时间 } printf("%lld\n",l); return 0; }