poj3104:Drying——贪心(二分+判定)

poj3104:Drying——贪心(二分+判定)

http://poj.org/problem?id=3104

Jane wants to perform drying in the minimal possible time. She asked you to write a program that will calculate the minimal time for a given set of clothes.

There are n clothes Jane has just washed. Each of them took ai water during washing. Every minute the amount of water contained in each thing decreases by one (of course, only if the thing is not completely dry yet).

Every minute Jane can select one thing to dry on the radiator. The radiator is very hot, so the amount of water in this thing decreases by k this minute (but not less than zero — if the thing contains less than k water, the resulting amount of water will be zero).

The task is to minimize the total time of drying by means of using the radiator effectively. The drying process ends when all the clothes are dry.

二分+判定性(可行性)

  • 选定一个时间t
  • 判定是否可在t时间内完成洗衣
  • 二分t选取可行的最小值

  • 吹风机下风干速率k,是自然风干和吹风机风干的叠加,即单纯吹风机风干速率是k-1
  • k==1的情况要单独考虑,因为此时k-1=0,会产生/0的异常
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;

#define ll long long

const int MAXSIZE = 1E5 + 10;
ll water[MAXSIZE];  //每件衣服含水量

/**
 * @brief 判定在时间times情况下是否可以完成洗衣
 * 
 * @param n n件衣服
 * @param k 使用吹风机风干时风干速率为k/minute
 * @param times 限定时间times
 * @return true 能够在限定时间times下完成所有洗衣
 * @return false 
 */

bool Judge(int n, ll k, ll times){
    ll sum = 0;
    for(int i = 0; i < n; ++i){
        if(water[i] > times){
            sum += ceil(1.0 * (water[i] - times) / (k-1));
        }
    }
    if(sum <= times){
        return true;
    }
    else{
        return false;
    }
}

int main(){
    int n;
    ll k;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i){
        scanf("%lld", &water[i]);
    }
    scanf("%lld", &k);
    sort(water, water + n);

    if(k == 1){
        printf("%lld\n", water[n-1]);
    }
    else{
        int left = 1;   //不能设置为water[0]
        int right = water[n-1];
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(Judge(n, k, mid)){
                right = mid - 1;
            }
            else{
                left = mid + 1;
            }
        }
        printf("%lld\n", left);
    }
    return 0;
}
posted @ 2022-02-08 09:03  dctwan  阅读(82)  评论(0编辑  收藏  举报