動態規劃之線性動規鋼條切割問題

2021-08-09 21:05:56 字數 1488 閱讀 5964

線性規劃是一類問題。目標函式為特定變數的線性函式,約束是這些變數的線性不等式(standard form)或等式(slack form),目的是求目標函式的最大值或最小值。這類動態規劃是平時比較常見的一類動態規劃問題。

假設公司**一段長度為i英吋的鋼條的**為pi(i = 1, 2, …單位:美元),下面給出了**錶樣例:

切割鋼條的問題是這樣的:給定一段長度為n英吋的鋼條和乙個**表pi,求切割方案,使得銷售收益rn最大。

當然,如果長度為n英吋的鋼條**pn足夠大,最優解可能就是完全不需要切割。

我們可以把他分解成兩個子問題,然後兩個子問題的最優解相加,再比較所有相加的和裡選出最優的。每個子問題也可以往下繼續分成兩個子問題,層層分下去。比如我現在長度為5,那麼就可以分成1+4、2+3。1+4裡面的4又可以劃分子問題,分成1+3、2+2、依此迴圈下去求出每個子問題的最優解後,與原來本數字的**比較,誰更大要誰,那麼總問題也就解決了

動規表示式:

max[n]=price[n]; (n=0)

max[n]=max(price[n],ri+rn-i) (n>0)

注:r代表大利潤

使用遞迴實現

static int dp(int n)

for(int i=0;i<=(n/2);i++)

return

max[n];

}

測試本頁資料通過,測試4的時候,for迴圈跑了8次。感覺效率很低,很多重複子問題都進行了求解,所以改進一下本演算法,儲存子問題的解,每次進行檢測,讓重複子問題不再進行二次求解,也就是我們說的動態規劃思想。犧牲一定的空間,換取時間。

帶備忘錄的自上而下求法。

static int dp(int n)

if(n==0)

for(int i=0;i<=(n/2);i++)

r[n]=max[n];

return

max[n];

測試長度為4時迴圈只跑了五次,大大提高了效率。

本題另外一種寫法

動規表示式:

rn=max(pi+rn-i)

int memorized_cut_rod_aux(int p, int n, int r)  

if (n==0)

else

} r[n]=q;

return q;

}

由以上鋼條切割問題我們發現,動態規劃有時並不是必須的,但是使用常規方法效率極其低下。而動態規劃之所以能提高程式的效率,是因為我們避免了重複子問題的求解。我們使用動態規劃總是在子子問題的基礎上求解子問題,再由子問題出求解最終的答案,而這一切的一切關鍵在於子問題的建立。

動態規劃之鋼條切割問題

鋼條切割方案自底向上 public class cutrodbottom2up public static void main string args private void start private cutrodsolution bottomupcutrod int n crsl.r j q ...

動態規劃 鋼條切割問題

已知鋼條切割的不同長度對應的不同 如下所示 長度i 1 23 45 67 89 10 pi 1589101717202430 求輸入長度,輸出最佳的收益。詳細理論知識見 演算法導論第十五章 p359 書中給出三個演算法 一 自頂向下遞迴實現 缺點 當n足夠大時,時間會 性地增長。偽 cut rod ...

動態規劃 鋼條切割問題

動態規劃與分治法相似,都是通過組合子問題的解來求解原問題。回顧下分治法的原理 它將問題劃分為互不相交的子問題 注意 互不相交 遞迴求解子問題,再將它們的解組合起來,即為原問題的解。但是,動態規劃與分治法不同,有以下幾點 1 對於子問題重疊的情況,分治法則重複求解,不高效。而動態規劃對每個子問題只求解...