poj 3104

/*
    题意:
        有n个衣服,每个衣服都有一个数值a[i],代表它的含水量。
        你要把所有衣服晾干,有两种方法:
            1.自然晾晒,每秒少1水
            2.风干机,每秒少k水,不足k则变为0,但是同一时间只可以风干一件衣服。
            
        求把所有衣服风干的最短时间。
    
    我们可以枚举时间mid。
    判断是否可以满足在mid时间内让所有的都变为0,如果可以,那么最终答案肯定<=mid,否则>mid。
    判断是否可以让mid满足:
        对于每个衣服,假如a[i]<=mid,那么自然风干就可以了,否则需要使用机器。
        我们可以使用贪心的策略来使用机器,对于衣服,可以使用机器t秒,然后自然风干,让总时间<=mid就可以了。
        
        t*k + mid - t >= a[i]
        有t >= (a[i] - mid)(k-1)
        
        k=1则之间输出a[i]最大的就可以了
        k!=1,t = ceil(....)
        
        把每个衣服的t加起来,就是风干机需要使用的总时间,如果不大于mid,那么满足条件,否则不行。
*/
#include <iostream>
#include <cstdio>
#include <cmath>

#define range(i,a,b) for (int i=a;i<=b;i++)

using namespace std;

const int maxn = 100000;

int a[maxn+1];
int n,k;

bool check(int val)
{
    int sum(0);
    range(i,1,n)
        if (a[i] <= val)
        {
            continue;
        }
        else
        {
            sum += ceil((double)(a[i]-val) / (k-1));
            if (sum > val)
                return 0;
        }
    return sum <= val;
}

int main()
{
    scanf("%d",&n);

    int L(0),R(0);

    range(i,1,n)
    {
        scanf("%d",&a[i]);
        R = R < a[i] ? a[i] : R;
    }
    scanf("%d",&k);


    if (k == 1)
    {
        cout<<R<<endl;
        return 0;
    }


    range(c,1,100)
    {
        int mid = (L+R) >> 1;
        if (check(mid))
        {
            R = mid;
        }
        else
        {
            L = mid;
        }
    }

    if (check(L))
        cout<<L<<endl;
    else
        cout<<L+1<<endl;

    return 0;
}
原文地址:https://www.cnblogs.com/dandi/p/4067218.html