题目地址:
https://leetcode.com/problems/cutting-ribbons/description/
给定 n n n条木棍及其长度,以数组 a a a形式给出。再给定一个正整数 k k k。对于某个长度 x x x,问是否可以将那些木棍截取出至少 k k k个长 x x x的小木棍。木棍不能拼接,只能剪断。
思路是二分。最短的长度是 1 1 1,最长的长度是 max a \max a maxa(否则切不出长度了),对于长度 x x x,切出的最多数量为 ∑ i ⌊ a [ i ] x ⌋ \sum_i \lfloor\frac{a[i]}{x}\rfloor ∑i⌊xa[i]⌋,其关于 x x x是单调的,从而可以二分。代码如下:
class Solution {
public:
int maxLength(vector<int>& rs, int k) {
int l = 1, r = 0;
for (int x : rs) r = max(r, x);
auto f = [&](int x) {
int cnt = 0;
for (int r : rs) cnt += r / x;
return cnt >= k;
};
while (l < r) {
int mid = l + (r - l + 1 >> 1);
if (f(mid)) l = mid;
else r = mid - 1;
}
return f(l) ? l : 0;
}
};
时间复杂度 O ( n log max a ) O(n\log \max a) O(nlogmaxa),空间 O ( 1 ) O(1) O(1)。