LeetCode 875-Koko Eating Bananas
题干:
给定一堆香蕉,共
n
n
n串,第
i
i
i串香蕉有piles[i]
根,Koko想把这堆香蕉在
h
h
h小时内全部吃完。
她吃香蕉的速度是 k k k根/小时,一小时内最多只吃一串里的香蕉。如果吃完了这串,该小时内也不再吃别的了;如果吃不完,剩余的就放在别的小时里吃。求她能在 h h h小时内全部吃完的最小速度 k k k。
Input: piles = [3,6,7,11], h = 8
Output: 4
解:
设Koko吃香蕉的速度为 x x x根/小时。可以得到,速度越大,越快吃完香蕉,花费的小时数越少;速度越小,越慢吃完,花费的小时数越大。 所以吃香蕉的速度和花费的时间是一个单调不递增函数关系。
所以,可以定义 f ( x ) f(x) f(x)函数为:以 x x x根/小时的速度吃香蕉,所花费的小时数。
又由题,需要限制 f ( x ) ≤ h f(x)\le h f(x)≤h。
所以该题所求的是:满足 f ( x ) ≤ h f(x)\le h f(x)≤h的条件下的最小 x x x。画图可得求的是左边界。
x
x
x的取值范围:left=1, right=max(piles[i])
long long f(vector<int>& piles, int x){
long long hour = 0;
for(auto i: piles){
hour += i/x;
if(i%x) ++hour;
}
return hour;
}
int minEatingSpeed(vector<int>& piles, int h) {
int left = 1, right = 1e9 + 1; //最小速度为1,最大速度为取值范围最大值(或给定数组的最大值)
int ans = 1e9;
while(left < right){
int mid = left + ((right - left) >> 1);
long long hour = f(piles, mid);
if(hour <= h){
ans = mid;
right = mid;
}
else if(hour > h) left = mid + 1;
}
return ans;
}