poj 3104 Drying

题目来源:POJ 3104

题目分析:
给你n件衣服,每件衣服有ai含水量,现有两种方式使他们变干:
1、自然蒸发,每分钟蒸发1滴水
2、烘干机烘干,每分钟蒸发k滴水(此时衣服不再自然蒸发)
求在给定k值的情况下,所有衣服变干的最小时间。
思路:
搜题解。
没想到是用二分的方法...看来自己的姿势水平还是太低,对于二分的理解仅限于单调数组中的搜索。
在网上偶然看到这样一句话,二分可以应用在这样的情况下:
对于一个真命题p(k),当m>=k时,仍有p(m)为真命题,此时可以考虑二分的方法。
仔细想想还是很有道理的,其实二分还是适用于一些具有“单调性质”的问题,比如这道题目,如果K分钟内能使所有衣服变干,那么K+1分钟一定可以,即对于任意M>=K,都可以完成题目要求。那么这道题,就需要二分枚举时间,思路如下:
对于某一个枚举时间T,所有含水量小于等于T的,都可以用自然蒸发的方法变干,我们就可以不用考虑它们。对于其余的衣服,因为我们希望在T时间内能够完成任务,即我们可以假定烘干机烘干时,每分钟蒸发k-1滴水,那么我们同时可以认为衣服仍然自然蒸发,在T时间内就会自然蒸发T滴,那么用烘干机烘干的时间就会是(ai-T)/(k-1)并且向上取整,把这些需要烘干机蒸发的时间累加起来,如果小于等于时间T,就说明在时间T内可以使所有衣服变干。需要注意的是,k=1需要特判。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
using namespace std;

int n;
int k;
int temp[100005];

bool ok(int x)   //判断枚举时间的可行性
{
    long long time=0;  //time累加的过程中可能爆int
    for(int i=1;i<=n;++i)
    {
        if(temp[i]>x)
        {
            if((temp[i]-x)%(k-1)==0)
                time+=(temp[i]-x)/(k-1);
            else
                time+=(temp[i]-x)/(k-1)+1;
        }
    }
    if(time<=x)
      return true;
    else
      return false;
}


int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&temp[i]);
    sort(temp+1,temp+1+n);
    scanf("%d",&k);
    int l=0;
    int r=temp[n];
    if(k==1)  //特判k=1的情形
        printf("%d\n",temp[n]);
    else
    {
        while(l<r-1) //注意二分的精度
        {
            int m=(l+r)/2;
            if(ok(m))
                r=m;
            else
                l=m;
        }
        printf("%d\n",r);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值