簡體   English   中英

何時使用自下而上 DP 何時使用自上而下 DP

[英]when to use bottom-up DP and when to use top-down DP

我已經學習了兩種DP方式,但我現在很困惑。 不同情況下我們如何選擇? 而且我發現在大多數情況下,自上而下對我來說更自然。 誰能告訴我如何做出選擇。

PS:我已經閱讀了這篇較舊的帖子,但仍然感到困惑。 需要幫忙。 不要將我的問題視為重復。 我已經提到它們是不同的。 我希望知道如何選擇以及何時從自上而下或自下而上的方式考慮問題。

為了簡單起見,我將根據我對一些來源的總結進行解釋

  1. 自上而下:看起來像: a(n) = a(n-1) + a(n-2) 使用這個等式,您可以a調用函數本身來使用大約 4-5 行代碼來實現。 正如您所說,它的優勢對大多數開發人員來說是非常直觀的,但它會花費更多的空間(內存堆棧)來執行。
  2. 自下而上:首先計算a(0)然后a(1) ,並將其保存到某個數組(例如),然后連續保存a(i) = a(i-1) + a(i-2) . 使用這種方法,您可以顯着提高代碼的性能。 使用 big n ,您可以避免堆棧溢出。

一個稍長的答案,但我試圖解釋我自己的動態規划方法以及在解決這些問題后我所理解的內容。 我希望未來的用戶覺得它有用。 請隨時發表評論和討論:

在考慮動態規划問題時,自上而下的解決方案更為自然。 您從最終結果開始,並嘗試找出實現目標的方法。 例如,對於 fib(n),我們知道我們只能通過 fib(n-1) 和 fib(n-2) 到達這里。 所以我們再次遞歸調用該函數來計算這兩種情況的答案,它會越來越深入到樹中,直到達到基本情況。 然后將答案建立起來,直到彈出所有堆棧並獲得最終結果。

為了減少重復計算,我們使用緩存來存儲新結果並在函數嘗試再次計算時返回它。 所以,如果你想象一棵樹,函數調用不必一直向下到樹葉,它已經有了答案,所以它會返回它。 這稱為記憶,通常與自上而下的方法相關聯。

現在,我認為對於自下而上的方法來說,重要的一點是您必須知道構建最終解決方案的順序。 在自上而下的情況下,您只是將一件事分解成許多,但在自下而上的情況下,您必須知道從一個級別到下一個級別的計算需要涉及的狀態的數量和順序。 在一些更簡單的問題中(例如 fib(n)),這很容易看出,但對於更復雜的情況,它並不自然適用。 我通常遵循的方法是自上而下思考,將最終案例分解為以前的狀態,並嘗試找到一種模式或順序,然后能夠將其重新構建。

關於何時選擇其中任何一個,我建議使用上述方法來確定狀態如何相互關聯以及如何構建。 您可以通過這種方式發現的一個重要區別是真正需要多少計算以及多少計算可能只是多余的。 在自下而上的情況下,您必須在進入下一個之前填充整個級別。 然而,在自上而下的情況下,如果不需要,可以跳過整個子樹,這樣可以節省很多額外的計算。

因此,選擇顯然取決於問題,但也取決於狀態之間的相互關系。 通常情況下,建議使用自下而上,因為與遞歸方法相比,它可以節省堆棧空間。 但是,如果您覺得遞歸不太深但很寬並且可能會通過表格化導致大量不必要的計算,那么您可以使用記憶化的自頂向下方法。

例如,在這個問題中: https ://leetcode.com/problems/partition-equal-subset-sum/,如果你看到討論,提到自上而下比自下而上快,基本上,二進制帶有緩存的樹方法與背包自下而上的構建。 我把它留作理解狀態之間關系的練習。

對於時間和空間復雜度方面的許多問題,自下而上和自上而下的 DP 方法是相同的。 不同之處在於,自下而上更快一點,因為您不需要遞歸的開銷,而且,是的,自上而下更直觀和自然。

但是,自上而下方法的真正優勢在於一些小的任務集,您不需要為所有較小的子任務計算答案。 在這種情況下,您可以降低時間復雜度。

例如,您可以使用帶記憶的自上而下方法來查找第 N 個斐波那契數,其中序列定義為 a[n]=a[n-1]+a[n-2] 所以,您有兩個 O( N) 計算它的時間(我不與 O(logN) 解決方案進行比較來找到這個數字)。 但是看看序列 a[n]=a[n/2]+a[n/2-1] 和一些小 N 的邊緣情況。在 botton up 方法中你不能比 O(N) 更快自上而下的算法將以復雜度 O(logN) 工作(或者可能是某種多對數復雜度,我不確定)

為了補充以前的答案,

  1. 最佳時間:
 if all sub-problems need to be solved → bottom-up approach else → top-down approach
  1. 最佳空間:自下而上的方法

Nikhil_10 鏈接的問題(即https://leetcode.com/problems/partition-equal-subset-sum/ )不需要解決所有子問題。 因此,自上而下的方法更為優化。

如果您喜歡自上而下的自然模式,那么在您知道可以實現它的情況下使用它。 自下而上比自上而下更快。 有時自下而上更容易,而大多數時候自下而上很容易。 根據您的情況做出決定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM