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