在討論二中,展示了鋼條分段的方法,只不過解題的方法採用的是自頂而下的策略。
個人理解的自頂而下的策略:
首先我們不知道乙個大問題的答案,但我們可以將問題規模縮小,外加上已知的一部分。進而變成求解這個小規模問題答案的過程,利用遞迴原理,層層向下,最終回到乙個最簡單的問題。
這種處理問題的方式,難免會有重複求解的情況出現。上篇中也有提到!!!
先還是把上篇的部分**搞過來看看。
int get_max(int* price,int* len,int num,int *p)//新增的這個指標p指向乙個記錄陣列,下標為長度num-1,我們用來記錄對應長度num下的最大收益
}p[num-1] =result;
return
result;
}
從**中,我們可以粗略計算下,總共呼叫了多少次get_max();首先在不斷的呼叫中,get_max()函式中的num值取遍了0-num,權且計作num次
在每次呼叫中,我們都需要for()迴圈下,(因為粗略計算嘛)我們就不考慮其中的if判斷了。
最終我們計算出的呼叫次數:num*6,很類似雙層迴圈啊
看num值從0變化到num的最大值
**從1到6變化,巢狀在num的每次變化,顯然是雙層迴圈了。
我們再分析下:
上述程式中,每次呼叫的get(..num..),都為了計算當前num的最大收益的吧。只不過大的num根據小的num計算出來,通過遞迴呼叫實現,但按照程式的實際執行的順序來說,最終還是小num的最大收益先被計算出,然後返回給大的num的使用。這是一種從頂向下,然後結果再層層上返回的過程。
與其這麼麻煩,我們不如先計算小num,然後將小num的值貢獻給比它大的num,這樣就減少了遞迴那樣不斷的呼叫了。(自下而上的策略)
這樣做的要求就是:我們必須保證num從1到最大時,每個迴圈都獲得當前num下的最大的收益,先上**好了:
void get_max(int* len,int* price,int n,int num,int *p,int* s)//其中n表示可分段種類數 num為鋼條長度,p記錄的當前num下首次截斷的長度,下標為num,s記錄的當前num下最大收益
if(s[i] >q)//當條件成立時,說明當前num下,最大收益的組合被更新了哦
}s[i] =q;
}}
這樣我們就獲得最大收益,同時也可以獲得如何分段的方法。
同時一定程度也減少了程式的複雜性。
如果下次再碰到動態規劃問題,就想想這個!理解比較淺薄,望指教!
遞迴本質討論
source click here 遞迴 分 遞推 和 回歸 遞迴的概念及遞迴演算法的結構 1 所謂的遞迴,是指函式在執行過程中自己呼叫了自己或者說某種資料結構在定義時又引用了自身。這兩種情況都可理解為遞迴。比如 void fun fun 以上函式fun就是乙個遞迴函式。而針對於各種資料結構中的遞迴...
初步遞迴續
我們來分析ff 3 的實現過程 同樣首先執行ff 3 根據判斷條件執行呼叫ff n 1 也就是ff 2 然後ff 2 呼叫ff 1 ff 1 執行 列印1 執行完畢 這個時候問題出現了,接下來會做什麼呢?我們會想到執行ff 2 但是從哪執行呢 是再次重新執行嗎?這樣肯定不會的否則會陷入無限迴圈中 實...
函式的遞迴(續)
漢諾塔問題 有三根柱子a,b,c a柱子上有n個盤子,把a柱子上的盤子全部移到c柱子上,一次只能移動乙個盤子,大的盤子不能放在小的盤子上面,求最少要移動多少次?分析 需要注意的是,只有把a柱子上 n 1 盤子移到b上,才能把a柱子第n個盤子移到c上.有1個盤子 直接移到c 1次 共 1次 有2個盤子...