题目:有 n 件刚洗完的衣服,其中第 i 件衣服上含有 ai 单位水分。
自然晾干的情况下,每件衣服每分钟可以减少 1 单位水分。
有一个可以使用的烘***,同一时间仅能容纳最多一件衣服。
在使用烘***的情况下,每件衣服每分钟可以减少 k 单位水分。
烘***每次使用的工作时间必须是整数分钟,不足 k 单位水分的衣服放入烘***,其包含水分最多降低至 0 ,而不会减为负值。
当衣服包含的水分变为 0 时,表示衣服已经干透了。
请你合理利用烘***,使得所有衣服干透所需的时间尽可能少。
输出所有衣服干透所需的最小可能分钟数。
输入格式: 第一行包含一个整数 n 。
第二行包含 n 个整数 a1,a2,…,an 。
第三行包含一个整数 k 。
输出格式 输出一个整数,表示所有衣服干透所需的最小可能分钟数。
数据范围 1≤n≤105 , 1≤ai≤109 , 1≤k≤109 。
思路:这是二分查找的应用,对于求最值问题的题,有暴力->二分查找->贪心->动态规划几种解法。其中二分查找要求该问题的结果与参数是单调(或突变)关系,像这道题就是随着时间(参数)不断变大,可以突然从不能完成任务,到完成任务。这就相当于已经排过序,利用二分查找(log n)的特性,可以缩短传统暴力枚举(n)的时间。
AC代码:
#include<iostream>
#include <cmath>
#include<algorithm>
using namespace std;
int a[100010];
int n;
int k;
bool check(int time)
{
int chuitime=0;
for (int i = 1; i <= n; i ++ )
{
if(a[i]<=time) {continue;}
chuitime+=(a[i]-time+k-1-1)/(k-1);//ceil(x/y)=>(x+y-1)/y;
if(chuitime>time) {return false;}//提前退出
}
return true;
}
int main()
{
cin>>n;
int maxx=0;
for (int i = 1; i <= n; i ++ ) {cin>>a[i];maxx = max(maxx, a[i]);}
cin>>k;
if(k==1) {cout<<maxx;return 0;}//k-1=0,而分母不能为0
//下面是二分查找,相当于找符合要求的第一个元素的类型
int l=1,r=maxx,mid=(l+r)/2;
while(l<r)
{
if(check(mid)) {r=mid;}
else{l=mid+1;}
mid=(l+r)/2;
}
cout<<l;
return 0;
}