作者:LeetCode-Solution
链接:https://leetcode-cn.com/circle/discuss/QGsghu/
来源:力扣(LeetCode)
题目
Q04 切分木棒
假设要把长度为 n 厘米的木棒切分为 1 厘米长的小段,但是 1 根木棒只能由 1 人切分,当木棒被切分为 3 段后,可以同时由 3 个人分别切分木棒。
求最多有 m 个人时,最少要切分几次。譬如 n = 8,m= 3 时如图 1 所示,切分 4 次就可以了。
提问:当 n = 20, m = 3 时的最少切分次数为 _____ ;当 n = 100, m = 5 时的最少切分次数为 _____ 。
官方解答
方法一:正向思维
思路与算法
我们可以模拟这个切分的过程。
设当前木棒的段数为 slices,初始时有slices=1。在每一次切分的过程中,如果 slices≥m,说明人数为瓶颈,只有 mm 段木棒会被切分;如果 slices<m,说明段数为瓶颈,只有slices 段木棒会被切分。因此每一次切分的木棒数量为 slices 和 m 中的较小值
min(slices,m)
这也是每一次切分后增加的段数。因此我们可以从初始时开始模拟,每次将木棒段数增加这个值,直到这个值大于等于 n 为止。
注意到题目中有一个要求是「将木棒切分为 1 厘米长的小段」,然而我们的方法看上去并没有规定切分的长度,甚至没有枚举切分了哪些木棒,但为什么这样做是对的呢?实际上,我们并不用在意这些,而是只要规定完成时所有的木棒的长度均为 1 厘米,这样我们就可以「倒推」出每一次切分时每一段木棒的长度,因此这一定是符合要求的。
class Solution {
public:
int cutBar(int n, int m) {
int slices = 1;
int cnt = 0;
while (slices < n) {
++cnt;
slices += min(slices, m);
}
return cnt;
}
};
自己又想了一个办法
如果有 m 个人那么当木棒数量 n 大于等于 m 时则不管怎么切 都最多能增加 m 段 如此循环则为 段数随着每次切依旧每次增加 m 段 直到总和大于等于 n 则完成
有一个注意点:当木棒数量小于人数时 则最多增加 木棒数量的段数 代码如下
很浅显易懂
int idea3()
{
int m = 5;
int n = 100;
int cnt = 0;
int nowNum = 0;
while(nowNum < m){
nowNum = pow(2.0,cnt);
cnt++;
}
cnt += ceil((n - nowNum)/m * 1.0);
return cnt;
}