動態規划和分治法的區別
動態規划也是一種分治思想(比如其狀態轉移方程就是一種分治),但與分治算法不同的是,分治算法是把原問題分解為若干個子問題,自頂向下求解子問題,合並子問題的解,從而得到原問題的解。動態規划也是把原始問題分解為若干個子問題,然后自底向上,先求解最小的子問題,把結果存在表格中,在求解大的子問題時,直接從表格中查詢小的子問題的解,避免重復計算,從而提高算法效率。
(1)最優子結構
是指問題的最優解包含其子問題的最優解。最有子結構是使用動態規划的最基本的條件,如果不具有最優子結構性質,就不可以使用動態規划解決。證明的例子
(2) 子問題重疊
子問題重疊不是使用動態規划的必要條件,但是問題存在子問題重疊的特性更能夠充分彰顯動態規划的優勢。
舉個例子:求斐波那契數列時fib(8)=fib(7)+fib(6),其中fib(8)的最優解就包含了子問題fib(7)的最優解和子問題fib(6)的最優解,反過來講只要我們求解出子問題的最優解,那么就可以構造出問題的最優解,這也就是為什么最優子結構是求解動態規划的必要條件。fib(7)和fib(6)中有相同的子問題fib(5),這就是子問題重疊。
(3) 動態規划的維數
斐波那契數列問題中的遞歸方程中只涉及一個變量i,所以是一維的動態規划,最長公共子序列問題中,遞歸方程中涉及兩個變量,是二維的動態規划。一個很直觀的理解就是,動態規划在從子問題的最優解來得到問題的最優解的過程中所填寫的那張表格是幾維的,就是幾維的動態規划。
最長公共子串(Longest Common Substring)與最長公共子序列(Longest Common Subsequence)的區別: 子串要求在原字符串中是連續的,而子序列則只需保持相對順序一致,並不要求連續。
(4) 如何驗證最優子結構特性
先寫出問題的最優解和子問題的最優解的關系,然后假定問題的最優解成立(上面關系的左邊成立),看能否得到子問題的最優解就是關系式右邊的子問題最優解的形式,如果是就驗證了最優子結構(一般用反證法)。