Drying POJ - 3104 (二分答案)

背景

每件衣服都有一定单位水分,在不适用烘干器的情况下,每件衣服每分钟自然流失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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/AlexLINS/p/12643092.html