• 2017.4.24 2.Drying [二分]


    Drying
    Time Limit: 2000MS Memory Limit: 65536K
    Total Submissions: 15519 Accepted: 3944
    Description

    It is very hard to wash and especially to dry clothes in winter. But Jane is a very smart girl. She is not afraid of this boring process. Jane has decided to use a radiator to make drying faster. But the radiator is small, so it can hold only one thing at a time.

    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). When amount of water contained becomes zero the cloth becomes dry and is ready to be packed.

    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.

    Input

    The first line contains a single integer n (1 ≤ n ≤ 100 000). The second line contains ai separated by spaces (1 ≤ ai ≤ 109). The third line contains k (1 ≤ k ≤ 109).

    Output

    Output a single integer — the minimal possible number of minutes required to dry all clothes.

    Sample Input

    sample input #1
    3
    2 3 9
    5

    sample input #2

    3
    2 3 6
    5

    题目大意:有n件湿度分别为a1,a2.....ai的衣服,如果自然烘干,每分钟湿度减少1。如果用吹风机进行烘干,每分钟湿度减少k(吹风机一次只能烘干一件衣服)。求能够烘干所有衣服的最小时间。1 ≤ n ≤ 100 000,1 ≤ ai ≤ 109,1 ≤ k ≤ 109.

    思路:利用二分。

    首先,烘干这些衣服所用的最大时间应该是在不用吹风机,让所有衣服自然烘干的情况下。则最大时间=MAX(a1,a2,a3....ai)。对(0,tmax]区间进行二分(因为t=0是不可能存在的情况,所以区间左边的值不能取,而区间右边的值可以取)

    开始时,令left=0,right=tmax。(注意:left的值是取不到的,而right的值可以取。之后的二分也要保持这种关系,进行二分的每个区间的最小值都是取不到的,而最大值可以取到)

    中值mid=(left+right)/2.

    此时要判断t=mid时,衣服能否烘干。判断mid是否符合的方法:

    对于第i件衣服:

    如果衣服的湿度ai<=mid,则这件衣服不必占用吹风机的时间,只需要自然烘干。

    如果衣服的湿度ai>mid,则这件衣服需要利用吹风机烘干一定时间才能够在规定时间内烘干。但至少要用多长时间的吹风机才能够烘干这件衣服? 设使用吹风机的时间为x,则剩下的(mid-x)时间内均在自然烘干,湿度每分钟减少1。已知吹风机每分钟可以烘干k的湿度,则可以得出式子kx+(mid-x)>=ai。移项可得x<=(ai-mid)/(k-1).因为x为整数,所以要用ceil向下取整。这样就可以求出第i件衣服利用吹风机的最小烘干时间。

    将每一件衣服需要利用吹风机的最小烘干时间相加,与mid比较。如果小于等于mid则表明t=mid时可以烘干完衣服,right=mid。大于mid则表明t=mid时不能烘干完衣服,left=mid。(这里mid没有+1或-1!!因为始终要保持left取不到,而right可以取的关系。结束二分的条件是R==L+1,因为由始到终保留的L时间不可行而R时间可行的属性,此时L不可能再大R也不可能再小,此时的R就是我们所要的最小值。如果right=mid-1,因为排除了mid,所以会失去mid这个可行解。如果left=mid+1,而mid+1可行,所以会漏掉mid+1这个解)

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 using namespace std;
     6 
     7 long long ai[100002];
     8 long long n;
     9 long long k;
    10 long long sumtime(long long mid)
    11 {
    12     long long hottime=0;
    13     for(int i=1;i<=n;i++)
    14         {
    15             if(ai[i]>=mid)
    16                 hottime+=(long long)ceil((double)(ai[i]-mid)*1.0/(k-1.0));
    17         }
    18     return hottime;
    19 }
    20 int main()
    21 {
    22     long long i;
    23     while(scanf("%lld",&n)!=EOF)
    24     {
    25         long long ans=0,tmax=0,tmin=0,mid=0;
    26         for(i=1;i<=n;i++)
    27             {
    28                 scanf("%lld",&ai[i]);    
    29             }
    30         sort(ai+1,ai+n+1);
    31         tmax=ai[n];
    32         scanf("%lld",&k);
    33         if(k==1)
    34             {
    35                 printf("%lld",tmax);
    36                 break;
    37             }
    38         while(1)
    39             {
    40                 mid=(tmax+tmin)/2;
    41                 if(sumtime(mid)<=mid)
    42                     tmax=mid;
    43                 else if(sumtime(mid)>mid)
    44                     tmin=mid;
    45                 if(tmax==tmin+1) 
    46                     {
    47                         ans=tmax;
    48                         break;
    49                     }
    50             }
    51         printf("%lld
    ",ans);
    52      }
    53     return 0;
    54 }
  • 相关阅读:
    SpringBoot整合Druid(阿里巴巴)数据源
    SpringBoot整合Jdbc
    SpringBoot使用外置的Servlet容器
    SpringBoot使用其他的Servlet容器
    question 002: dev c++ 当中如何调整字体大小?How to get the first program with C++? c++属于什么软件?
    c++ 程序设计question 001:我们的开发工具是什么?
    问题007:JDK版本与JRE版本不同导致java.exe执行类文件错误 java.lang.UnsupportedClassVersionError错误
    问题006:为什么用java.exe执行编译的类文件的时候,不这样写java Welcome.class
    问题005:如何配置JDK,Java运行环境?
    DOS当中的基本操作命令,如何切换磁盘,如何查看文件和文件夹,如何清屏,进入文件夹的命令,javac是什么意思,作用是什么?DOS如何建文件夹?退出文件夹?
  • 原文地址:https://www.cnblogs.com/iron-/p/6758747.html
Copyright © 2020-2023  润新知