分治和動態規劃都是解決較大規模問題比較困難或者無法直接求解的場景下的策略,兩者之間有相同點,也有不同點。
相同點:
(1) 原問題需要具有最優子結構性質;
(2) 解決思路都是將原問題分解成若干個規模較小的子問題。
不同點:
(1) 分治法要求子問題之間相互獨立,子問題的分解中不能包含公共子問題;
(2) 動態規劃是應對子問題之間有重複的解決方案;
(3) 分治法一般採用遞迴來求解;
(4) 動態規劃一般採用迭代法通過自底而上求解,或者通過具有記憶功能的迭代自頂而下求解。
通過上述分析的相同點和不同點,我們能夠在遇到問題的時候,選擇合適的策略求解。
例題分析
分治法快速冪運算:
對於給定的底數和指數冪,直接暴力計算的話,時間複雜度為o(n)。
根據數學知識,可知:
a^(n + n) = a ^n * a^n
通過上述性質,可以使用分治法對暴力冪運算進行優化,優化之後的時間複雜度為o(log n)。**如下:
1動態規劃演算法的leetcode 例題:deffastpow(a, b):
2 ans = 1
3 base =b
4whileb:5
if b & 1:
6 r *=base
7 base *=base
8 b >> 1
9return ans
乙個機械人位於乙個 m * n 網格的左上角
(起始點在下圖中標記為「start」 )。
機械人每次只能向下或者向右移動一步。機械人試圖達到網格的右下角(在下圖中標記為「finish」)。
問總共有多少條不同的路徑?
在這道題中,我們首先設定dp[i][j] 為start 到點(i, j) 的最優策略(也就是題目中要求解的不同路徑數),首先
dp[0][0] = 1
。由給定性質,只能向下或者向右可以得出,dp[0][j] 和
dp[i][0] 均為1
。對於其他位置的點(i, j):
因為只能向下走,所以唯一確定dp[i - 1][j] 對
dp[i][j]
有貢獻;
因為只能向右走,所以唯一確定dp[i][j - 1] 對
dp[i][j]
有貢獻。
由上述性質可得出遞推公式:
dp[i][j] = dp[i][j - 1] + dp[i - 1][j]
在本題中,需要求解的只是給定問題的最優解,不是內部其他子問題的最優解,所以二維陣列可以優化。
仔細觀察遞推公式可以發現,當前點(i, j) 只與本行當前位置之前的資料和上一行當前位置的資料有關。
即,上述儲存解的空間可優化為乙個一維的陣列:
dp[n] = dp[n] + dp[n - 1]
演算法的時間複雜度為o(m*n),空間複雜度為
o(n)
。下面是**:
1class
solution(object):
2def
uniquepaths(self, m, n):
3"""
4:type m: int
5:type n: int
6:rtype: int
7"""
8 cur = [1] *n
9for i in range(1, m):
10for j in range(1, n):
11 cur[j] += cur[j - 1]
12return cur[-1]
分治演算法和動態規劃
分治法與動態規劃主要共同點 二者都要求原問題具有最優子結構性質,都是將原問題分而治之,分解成若干個規模較小 小到很容易解決的程式 的子問題.然後將子問題的解合併,形成原問題的解.分治法與動態規劃實現方法 分治法通常利用遞迴求解.動態規劃通常利用迭代法自底向上求解,但也能用具有記憶功能的遞迴法自頂向下...
最大子段和 分治與動態規劃
問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...
最大子段和 分治與動態規劃
問題 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為 max,1 i j n 例如,當 a1,a2,a3,a4,a4,a6 2,11,4,13,5,2 時,最大子...