假設要把長度為n厘公尺的木棒切分為1厘公尺長的小段,但是1根木棒只能由1人切分,當木棒被切分為3段後,可以同時由3個人分別切分木棒。求最多有m個人時,最少要切分幾次。
譬如n=8,m=3時如下圖所示,切分4次就可以了。
求當n=20,m=3時的最少切分次數。
求當n=100,m=5時的最少切分次數。
這道題最難的不是演算法,而是理解題意。
木棒剛開始只有1根,題目規定「1根木棒只能由1人切分」,此時由1人切分後,變成2根;
2根木棒再做切分,也要滿足「1根木棒只能由1人切分」的規則,所以此時由2個人,每人切1根,變成了4根;
隨後,題目說「當木棒被切分為3段後,可以同時由3個人分別切分木棒」,也就是說,
當木棒根數達到上限人數後,每一次便只能切分出上限人數的根數了。
而在這之前,每次都有足夠的人切木棒,每次也都是一分為二,木棒的數量都是翻倍遞增
用文本來描述便是:
當前木棒數量 >= 人數上限時,新木棒數量 = 原有木棒數量 + 上限人數;此題可以用遞迴和迴圈兩種方法來解。當前木棒數量 < 人數上限時,新木棒數量 = 原有木棒數量 * 2;
當新木棒數量大於等於木棒長度時,切分結束。
遞迴:
遞迴的結束條件便是current(當前的木棒數)>= n (木棒長度)。迴圈:當current (當前的木棒數)< m(人數上限)時,current = current * 2。
當current(當前的木棒數)>= m (人數上限)時,current = current + m;
每次遞迴時,就將當前木棒數通過引數傳入下一次遞迴中,直至滿足退出條件。
迴圈的結束條件與遞迴一樣,也是當current(當前的木棒數)>= n (木棒長度)時退出,即是current < n時一直執行迴圈。php當current (當前的木棒數)< m(人數上限)時,current = current + current。
當current(當前的木棒數)>= m (人數上限)時,current = current + m;
每執行一次迴圈,count(迴圈計數,即切分次數)加1。
// 遞迴
// m 為上限人數
// n 為木棒長度
// current 為當前木棒數量
function cutbar($m, $n, $current)
elseif ($current < $m) else
}// 迴圈
function cutbar2($m, $n)
return $count;
}$rs = cutbar(3, 8, 1);
echo $rs."\n";
$rs = cutbar(3, 20, 1);
echo $rs."\n";
$rs = cutbar(5, 100, 1);
echo $rs."\n";
$rs = cutbar2(3, 8);
echo $rs."\n";
$rs = cutbar2(3, 20);
echo $rs."\n";
$rs = cutbar2(5, 100);
echo $rs."\n";
輸出:
4822
4822
golang
package main
import "fmt"
func main()
func cutbar(m, n, current int) int else if current < m else
}func cutbar2(m, n int) int else
count++
}return count
}
輸出:
4822
4822
每週一道LeetCode演算法題 兩數之和
class solution return result 分析class solution for int i 0 i nums.length i throw newillegalargumentexception no two sum solution class solution map.put...
程式設計訓練 每週一道程式設計題(九)
題目 給出乙個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。注意 假設我們的環境只能儲存得下 32 位的有符號整數,則其數值範圍為 2 31,2 31 1 請根據這個假設,如果反轉後整數溢位那麼就返回 0。例子 輸入 123 輸出 321輸入 123 輸出 321思路 分兩種情況討...
程式設計訓練 每週一道程式設計題(十)
題目 編寫乙個函式來查詢字串陣列中的最長公共字首。如果不存在公共字首,返回空字串 示例 輸入 flower flow flight 輸出 fl 輸入 dog racecar car 輸出 解釋 輸入不存在公共字首。說明 所有輸入只包含小寫字母a z。思路 定義乙個新的字串,如果陣列中每一項都是以這個...