演算法 動態規劃 1 鋼條切割

2021-09-24 20:55:37 字數 1515 閱讀 4073

dynamic programming 動態規劃,與分治法相似,都是通過組合子問題的解來求解原問題,但動態規劃是應用於子問題重疊的場景,每個子問題都只求一遍,將解存入**中,避免不必要的重複工作。

問題:購買長鋼條,將其切割為短鋼條**,不同長度的鋼條對應不同的**,希望得到最佳的切割方案使利潤最大化。

長度 i12

3456

78910

** p15

891017

1720

2430

先把結果放出來

鋼條長度

切割方案

最大價值11

1225

3384

2+210

52+3136

61771+6或2+2+3188

2+622

93+6

2510

1030

由大化小,因為這種切割問題滿足最優子結構性質,所以我們尋找更小一些的子問題,尋找迴圈不變的問題,即無論哪一次切割,我切割之後會產生兩段鋼條,而這兩段鋼條產生了最大的收益,之後這兩段鋼條再去迴圈上述過程,直到切割完成;

遞迴,將鋼條切成兩塊,遞迴這個過程,最後比較結果產生最優解

動態規劃

前兩種屬於樸素遞迴方法,反覆求解相同的子問題,效率很低,執行時間為n的指數函式,而動態規劃每次執行都儲存了結果,在下次執行相同子問題是會直接使用結果而不用重複計算,提高了效率

動態規劃有兩種等價的實現方式

自頂向下,備忘錄式

自底向上

自頂向下:仍然按照遞迴形式,過程中儲存沒格仔問題的解,而後遇到子問題都回去查是否之前儲存過,節省時間,所以又稱是帶有備忘錄的演算法

自底向上:這種方法需要把子問題按照規模排序,由小到大進行求解,因為大問題會依賴與小規模的問題,由於小問題已經求解完畢也相當於儲存了之前的結果。

這兩種方式漸進執行時間相同,但考慮細節,後者沒有頻繁遞迴,所以時間複雜度有更小的係數,當然次數越大係數就越不重要

這裡貼出來後者實現解決問題的**供參考

/**

* author: qit .

* date: on 2019/6/28

*/public class test ;

static int r = new int[p.length];

public static void main(string args)

private static int getmaxvalue(int length)

private static int memoized_aux(int n, int r, int p)

if (n == 0)

return q = 0;

else

for (int i = 1; i <= n; i++)

r[n] = q;

system.out.println(n + "---" + r[n]);

return q;

}}

動態規劃 鋼條切割

一家公司購買長鋼條,將其切割成短鋼條 切割本身沒有成本,長度為i的短鋼條的 為pi。那給定一段長度為n的鋼條和乙個 表pi,求鋼條的切割方案使得收益rn最大。如乙個pi如下 長度i12 3456 78910 pi15 891017 1720 2430 在距離鋼條左端i長度處,我們總是可以選擇切割或者...

動態規劃 鋼條切割

這是演算法導論動態規劃的乙個例子,自己實現了一下 給定乙個長度為n英吋的鋼條和乙個 表pi i 1,2 n 求切割鋼條方案,使得銷售收益rn最大。注意,如果長度為n的鋼條 pn足夠大,則最優解可能就不需要切割。分析 如下 include include include using namespace...

動態規劃 鋼條切割

動態規劃 dynamic programming 什麼是動態規劃,我們要如何描述它?動態規劃演算法通常基於乙個遞推公式及乙個或多個初始狀態。當前子問題的解將由上一次子問題的解推出。動態規劃和分治法相似,都是通過組合子問題的解來求解原問題。分治法將問題劃分成互不相交的子問題,遞迴求解子問題,再將他們的...