模板
int bsearch_1(int l, int r) {
while (l < r) {
int mid = (l+r)>>1;
if (check(mid)) {
r = mid; // check()判断mid是否满足性质
} else {
l = mid + 1;
}
}
return l;
}
例题,来源字节笔试题:
给定n个猴子 每个猴子有个食量,每个猴子轮流拿香蕉,要求拿的数量为min(remain/2,eat*2)且该数量>eat,其中remain是当前剩余食物数量,eat是食量。最后一个猴子可以全部拿走,求最小的食物数量使得每个人都能吃饱。
虑到这个食物数量肯定是单调的,那么二分答案即可
vector<int> v;
int a;
int check(int mid) {
for (int i = 0; i + 1 < v.size(); i++) {
int num = min(mid / 2, v[i] * 2);//当前猴子拿走num
if (num < v[i]) return 0;
mid -= num;//拿走一次后还剩下的香蕉
}
if (mid < v.back()) return 0;
return 1;
}
int main() {
while (cin >> a) {
v.push_back(a);
}
int l = 1, r = 1e9 + 7;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
printf("%d\n", l);
return 0;
}
leetcode 875
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int H) {
int left = 1, right = 1e9+7;
while (left < right) {
int mid = (left + right)>>1;
if (check(piles, H, mid)) right = mid;
else left = mid+1;
}
return left;
}
bool check(vector<int>& piles, int H, int speed) {
int time = 0;
for (int p: piles)
time += (p - 1) / speed + 1;//向上取整
return time <= H;
}
};
9.10更新
来自b站一个up主,讲的挺好的,真·万能,不用担心越界