日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

切木头之二分法启示

發布時間:2025/3/8 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 切木头之二分法启示 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

183. 木材加工

有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭,需要得到的小段的數目至少為 k。當然,我們希望得到的小段越長越好,你需要計算能夠得到的小段木頭的最大長度。 木頭長度的單位是厘米。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也要求是整數。無法切出要求至少 k 段的,則返回 0 即可。

解釋一下就是:給定了一個切割目標長度Len后,每一根原木都可以切割出多條,加在一起的數目totalCount要求大于等于k。在滿足總數目totalCount大于等于k的條件下,得到一個最長的目標長度len。

暴力解

首先想到的是暴力解,當len給定,totalCount就可以計算出來,而且可以知道len越小,totalCount就越大。那么從最長的原木長度maxLen開始算總數,第一個滿足totalCount>=k就是我們要的解。

時間復雜度是n*(maxLen-targetLen),隨機情況來看,每個長度概率一樣,就是n*(∑k/maxLen), 1<=k<=maxLen,即O(n*maxLen)。

這個肯定是不夠的。

動態規劃

對于最有解的問題,很自然的會想到動態規劃,而動態規劃的核心的找到大問題向小問題的轉移方式。在這一題里,也就是找到切割目標長度len時的總數和len+1時的總數之間的關系,倘若這兩者直接的計算復雜度為O(x),那么總復雜度為O(x*maxLen),那么只要x<n就可以得到優化。

有什么辦法可以讓兩個總長度直接關聯得到計算,而不需要再次循環一個個原木從新計算呢?這個我嘗試了,沒想出來。

二分法

然后看了眼題目的標簽,是二分法,瞬間感覺有戲了。 這個情況里最有用的一個分析是:目標長度len越小,總數totalCount就越大。對比一個二分查抄的邏輯,找到一個目標來分隔區間,然后不斷的縮小區間,最后剩下的是解。這里就是:一開始的選擇區間是[1,maxLen],取中數mid,求出總數,和k比較,如果總數小,那么就要繼續壓小長度,那么選擇區間就變成了[1,mid],反之選擇區間就是[mid,maxLen]。按照這樣的思路,區間不斷縮小,最后找到解。

int woodCut(vector<int> &L, int k) {int maxLen = 0;int residue = k;for (int len : L){if (residue>0) {residue -=len; //不直接比較總量是因為可能會超出int范圍}maxLen = max(maxLen, len);}//排除頭<kif (residue > 0) {return 0;}//排除尾>=kint maxLenCount = 0;for (int len : L){if (len == maxLen) {if ((++maxLenCount)==k) {return maxLen;}}}//循環不變條件是:左邊結果>=k,右邊<k。所以前面先把不滿足的頭和尾情況排除,逼近到最后left和right相鄰時,left就是解。int left = 1, right = maxLen;while (left < right-1) {int mid = left+(right-left)/2;int count = 0;for (int len : L){count += len/mid;}if (count<k) {right = mid;}else{left = mid;}}return left; } 復制代碼
啟示

這題給我最大的一個啟示是:二分法的使用跟環境存在一個單調遞增或遞減的關系是緊密相關的

假設存在兩個變量A和B,A和B的關系是單調遞增或遞減,假設為遞增,即A月大則B越大。然后我們要求B為b'時的A的值a',那么就可以用二分法了。

先來一個區間[a1, a2],只要a1和a2對應的B值是在目標的兩邊,即一個大于目標一個小于目標,那么就可以用二分法的手段不斷的壓縮區間直到最后找到解。

那如果a1,a2對應的B值在同一邊呢?那么一般這種情況下, 已經到了邊緣還沒有解,就是求最近的數,那么解就是a1或者a2。

解算法題,找到對應的解法模型問題就會很快,那怎么知道某一題對應了什么樣的解法模型,我覺得就是有一些引子、征兆之類的東西,這才是我想說的,這個切木頭題目只是個例子。對于二分法,它的一個征兆就是存在兩個變量,它們之間有單調遞減或遞增的關系。

總結

以上是生活随笔為你收集整理的切木头之二分法启示的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。