二分解决最小最大问题
1.2064. 分配给商店的最多商品的最小值
题目描述:
给你一个整数 n ,表示有 n 间零售商店。总共有 m 种产品,每种产品的数目用一个下标从 0 开始的整数数组 quantities 表示,其中 quantities[i] 表示第 i 种商品的数目。
你需要将 所有商品 分配到零售商店,并遵守这些规则:
一间商店 至多 只能有 一种商品 ,但一间商店拥有的商品数目可以为 任意 件。分配后,每间商店都会被分配一定数目的商品(可能为 0 件)。用 x 表示所有商店中分配商品数目的最大值,你希望 x 越小越好。也就是说,你想 最小化 分配给任意商店商品数目的 最大值 。请你返回最小的可能的 x 。
示例 1:
输入:n = 6, quantities = [11,6] 输出:3 解释:一种最优方案为:
- 11 件种类为 0 的商品被分配到前 4 间商店,分配数目分别为:2,3,3,3 。
- 6 件种类为 1 的商品被分配到另外 2 间商店,分配数目分别为:3,3 。分配给所有商店的最大商品数目为 max(2, 3, 3, 3, 3, 3) = 3 。
题解:
某个商店所需要的商品数量为:商品总数/最大分配数 向上取整,如果满足n间商店,就不断缩小分配数,这样便得到了最小分配给商店的最大值。
实现:
我们使用二分搜索,着重点是check方法,求每个商店的商品数量,然后累加 看看是否不超过商店总数。
代码语言:javascript复制class Solution {
public:
int minimizedMaximum(int n, vector<int>& q) {
int l = 1, r = 1e5;
while (l < r) {
int m = (l r) >> 1;
if (check(n, q, m)) {
r = m;
} else {
l = m 1;
}
}
return l;
}
bool check(int n, vector<int>& q, int m) {
int sum = 0;
for (int i = 0; i < q.size(); i ) {
sum = (q[i] m - 1) / m;
}
return sum <= n;
}
};
2.珂珂喜欢吃香蕉。
题目描述:
这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 H 小时后回来。
珂珂可以决定她吃香蕉的速度 K (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 K 根。如果这堆香蕉少于 K 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。
珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。
返回她可以在 H 小时内吃掉所有香蕉的最小速度 K(K 为整数)。
示例 1:
输入: piles = [3,6,7,11], H = 8 输出: 4
题解:
我们知道要让H小时内吃掉,每次肯定吃得多,那么才有可能吃完,不然吃不完了,实际上就是吃最多香蕉,题目变为最小化(速度)吃掉所有香蕉的最大值。
跟上面题目一样。
实现:
代码语言:javascript复制class Solution {
public:
int minEatingSpeed(vector<int>& piles, int h) {
int l = 1, r = 1e9;
while (l < r) {
int m = (l r) >> 1;
if (check(piles, h, m)) {
r = m;
} else {
l = m 1;
}
}
return l;
}
bool check(vector<int>& piles, int h, int m) {
int sum = 0;
for (int i = 0; i < piles.size(); i ) {
sum = (piles[i] m - 1) / m;
}
return sum <= h;
}
};