ACM總結——動態規劃(1)重疊子問題、最優子結構

動態規劃(dynamic programming)簡稱DP。

DP系列:

ACM總結——動態規劃(1)重疊子問題、最優子結構
https://blog.csdn.net/nameofcsdn/article/details/106417240
ACM總結——動態規劃(2)問題本身的固有屬性決定數據結構和算法
https://blog.csdn.net/nameofcsdn/article/details/106436743
ACM總結——動態規劃(3)空間壓縮
https://blog.csdn.net/nameofcsdn/article/details/106507259
ACM總結——動態規劃(4)問題的形式化描述
https://blog.csdn.net/nameofcsdn/article/details/106497777
ACM總結——動態規劃(5)二維DP
https://blog.csdn.net/nameofcsdn/article/details/106559659

 

先看幾個簡單的問題:

1,斐波那契數列

1,1,2,3,5,8......

求第n項

int fac(int n)
{
    if(n<3)return 1;
    return fac(n-1)+fac(n-2);
}

時間複雜度O (1.6 ^ n)

遞歸寫法(備忘錄法):

int ans[1000]={0};
int fac(int n)
{
    if(n<3)return 1;
    if(ans[n])return ans[n];
    return ans[n]=fac(n-2)+fac(n-1);
}

非遞歸寫法:

int ans[1000]={0,1,1};
int fac(int n)
{
    for(int i=3;i<=n;i++)ans[i]=ans[i-1]+ans[i-2];
    return ans[n];
}

遞歸寫法不需要控制DP的計算順序,非遞歸寫法需要嚴格控制計算順序。

讀者可此處思考一下上述遞歸寫法的實際計算順序,假設編譯器是默認先執行加法左邊的,再執行加法右邊的。

兩種寫法的時間複雜度都是O(n)

爲什麼差異這麼大?

這就是DP的第一個重要特性:重疊子問題

 

2,求數列中位數

這個題,能不能像上一題這麼做呢?

如果我用f(n)表示數列前n個數的中位數,那麼,由f(n-1)和f(n-2)可以直接推導出f(n)嗎?

不能!

差異在哪?差異在於問題本身的性質不同。

這種由子問題的答案可以直接推導出原問題答案的性質,其實就是最優子結構。

最優子結構:問題的最優解包含了子問題的最優解

 

再來看看一個動態規劃的題目,當我們分析它的時候,我們在想些什麼?

3,數列的DP問題

一維

力扣 OJ 300. 最長上升子序列

https://blog.csdn.net/nameofcsdn/article/details/104086350

力扣OJ 1218. 最長定差子序列

https://blog.csdn.net/nameofcsdn/article/details/106418150

二維

力扣 OJ 1143. 最長公共子序列

https://blog.csdn.net/nameofcsdn/article/details/104091938

CSU - 1060 Nearest Sequence (三個數組的最長公共子序列)CSU - 1060 Nearest Sequence (三個數組的最長公共子序列)

https://blog.csdn.net/nameofcsdn/article/details/79697208

 

4,最短路問題

 

動態規劃的題目,當我們分析它的時候,主要就是:

問題研究的對象、問題的子問題、最優子結構(即遞推式)、解空間結構

遞歸寫法和非遞歸寫法其實都是解空間的遍歷,而絕大部分問題的解空間都可以映射爲樹空間,樹的遍歷主要就是DFS和BFS,遞歸基本上就是DFS。

 

什麼是解空間結構?

解空間就是問題可能的解組成的集合,根據問題的屬性,空間的結構也有不同,有的是數組有的是樹等等。

 

 

 

按照問題研究的對象類型和解空間結構,DP問題可以分爲數列DP、區間DP、樹形DP、數位DP、狀態壓縮DP、概率與期望DP、高維DP等等。

 

DP的更深用法:

空間壓縮、時間優化

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章