Day2補充 鋼管切割問題

2021-09-24 20:01:31 字數 1568 閱讀 5542

**:

某公司生產長鋼管,然後一般,會將鋼條切斷,變成不同長度,然後去售賣。其中有個問題是,不同長度的鋼管的售價是不一樣的,但是它們並不是完全按照比例來,比如2公尺的鋼管售價要比3公尺的鋼管售價要少,但是並不是2比3的比例。鋼管的長度售價表如下:

長度i123

4567

8910**

891017

1720

2430

於是問題就來了,比如30公尺長的鋼管,要如何切割,切割成多長的幾條,才能讓售價最高,收益最高呢?

1.樸素演算法:

最簡單直接的想法,就是用暴力破解,n長的鋼管,可以分解成i長和n-i長的兩段,因為i可以從0~n取值,所以我們可以對i不進行繼續切割,於是對於長為i的這一段,可以直接呼叫價錢陣列p[i]來得到價錢,然後加上對n-i遞迴呼叫求最優收益的函式的返回值。在過程之中記錄這些組合的最優收益,等迴圈結束的時候,就能得到最優的收益價錢。

假設r[n]代表的是n長的鋼管的切割最佳收益值,陣列p代表上面表中的**,其中p[0]=0,從p[1]~p[10]對應上面表中的資料,那麼按照上面的想法,有公式:

這種方法比較容易理解,但是效能是不是好呢?

可以簡單的以n=4的情況來看一下:

n=4的劃分(其中前面的那一段是直接使用p[i],後面一段呼叫函式來求最佳收益):

cut_rod(p,4)的劃分可能:

①1長和3長:p[1]+cut_rod(p,3)

②2長和2長:p[2]+cut_rod(p,2)

③3長和1長:p[3]+cut_rod(p,1)

④4長和0長:p[4]+cut_rod(p,0)

而其中cut_rod(p,3)又可以劃分為陣列p中元素與cut_rod(p,0),cut_rod(p,1)和cut_rod(p,2);以此類推,可以給出一種以遞迴呼叫樹的形式展示cut_rod遞迴呼叫了多少次:

不難從圖中看出,做了大量重複工作,以n=2的節點為例,分別在n=4和n=3的時候都被呼叫了。根據上圖,可以給出遞迴呼叫次數的乙個公式,假設t(n)表示cut_rod第二個引數為n時的呼叫次數,t(0)這時候是為1的,因為根結點的第一次呼叫也要算進去。於是有:

t(n)=1+t(0)+t(1)+...+t(n-1)

使用歸納法,可以比較容易的得出:t(n)=2^n。

指數次冪的呼叫次數,顯然太大,我們稍微讓n大一點,則會讓整個過程變的漫長。

2. 動態規劃演算法

而實際上我們不需要在每次都去重新計算cut_rod的在n=2時的結果,只需要在第一次計算的時候將結果儲存起來,然後再需要的時候直接使用即可。這其實就是所謂的動態規劃演算法。

這裡的思路有兩種,一種叫帶備忘的自頂向下方法,是順著之前的**,當需要的時候去檢查是不是已經計算好了,如果是,則直接使用,如果不是,則計算,並儲存結果。第二種思路是自底向上方法,不論需不需要,先將子問題一一解決,然後再來解決更高一級的問題,但要注意的是,我們需要先從最小的子問題開始,依次增加規模,這樣每一次解決問題的時候,它的子問題都已經計算好了,直接使用即可。

動態規劃 鋼管切割問題

給一條鋼管,切割成不同長度的鋼管 也可以不切割 不同的鋼管長度對應不同的價值,求這根鋼管獲得的最大價值。輸入 第一行包含乙個正整數l,為鋼管的長度。第二行包含l個正整數a1 al,為長度從1到l的鋼管對應的價值。輸出 輸出一行,為鋼管能獲得的最大價值。輸入樣例1 5 1 2 4 8 16 輸出樣例1...

DAY2補充3 定位 WEB前端

1 概述 day2補充3,介紹html中定位的所有型別和相關用法。博主在浮動篇簡單提到過定位,這裡更加詳細的介紹。2 定位 2.1 什麼是定位?定位元素框相對於其正常位置應該出現的位置 定位分類 1 普通流定位 文件流 預設 2 浮動定位 3 相對定位 4 絕對定位 5 固定定位 2.2 定位的屬性...

演算法導論 動態規劃之「鋼管切割」問題

動態規劃,其實跟分治法有些相似,基本思想都是將複雜的問題分成數個簡單的子問題,然後再去解決。它們的區別在於,分治法關注的子問題不相互 重疊 而動態規劃關注的子問題,多是相互 重疊 的。比如在快速排序中,我們將資料分成兩部分,這兩部分再分別快速排序的遞迴思想,也就是將整個問題的排序劃分為子問題子陣列的...