动态规划算法学习
? 筆試面試中經(jīng)常會(huì)出現(xiàn)一些考察動(dòng)態(tài)規(guī)劃方面的題目,以前沒(méi)有接觸過(guò),現(xiàn)在初學(xué)做個(gè)整理。
1. 什么是動(dòng)態(tài)規(guī)劃?
???????? 和分治法一樣,動(dòng)態(tài)規(guī)劃(dynamicprogramming)是通過(guò)組合子問(wèn)題而解決整個(gè)問(wèn)題的解。
???????? 分治法是將問(wèn)題劃分成一些獨(dú)立的子問(wèn)題,遞歸地求解各子問(wèn)題,然后合并子問(wèn)題的解。
???????? 動(dòng)態(tài)規(guī)劃適用于子問(wèn)題不是獨(dú)立的情況,也就是各子問(wèn)題包含公共的子子問(wèn)題。
???????? 此時(shí),分治法會(huì)做許多不必要的工作,即重復(fù)地求解公共的子問(wèn)題。動(dòng)態(tài)規(guī)劃算法對(duì)每個(gè)子問(wèn)題只求解一次,將其結(jié)果保存起來(lái),從而避免每次遇到各個(gè)子問(wèn)題時(shí)重新計(jì)算答案。
2. 動(dòng)態(tài)規(guī)劃算法的設(shè)計(jì)
兩種方法:
???????? 自頂向下(又稱記憶化搜索、備忘錄):基本上對(duì)應(yīng)著遞歸函數(shù)實(shí)現(xiàn),從大范圍開(kāi)始計(jì)算,要注意不斷保存中間結(jié)果,避免重復(fù)計(jì)算
???????? 自底向上(遞推):從小范圍遞推計(jì)算到大范圍
動(dòng)態(tài)規(guī)劃的重點(diǎn):
???????? 遞歸方程+邊界條件
3. 爬樓梯問(wèn)題
???????? 一個(gè)人每次只能走一層樓梯或者兩層樓梯,問(wèn)走到第80層樓梯一共有多少種方法。
???????? 設(shè)DP[i]為走到第i層一共有多少種方法,那么DP[80]即為所求。很顯然DP[1]=1, DP[2]=2(走到第一層只有一種方法:就是走一層樓梯;走到第二層有兩種方法:走兩次一層樓梯或者走一次兩層樓梯)。同理,走到第i層樓梯,可以從i-1層走一層,或者從i-2走兩層。很容易得到:
???????? 遞推公式:DP[i]=DP[i-1]+DP[i-2]
???????? 邊界條件:DP[1]=1?? DP[2]=2
???????? (a)自頂向下的解法:
???????? (b)自底向上的解法:
[cpp]?view plaincopy 4. 最長(zhǎng)上升子序列
???????? 對(duì)于序列:4 1 2 24,它的最長(zhǎng)上升子序列是1 2 4,長(zhǎng)度為3。
???????? 對(duì)于序列:4 2 4 25 6,它的最長(zhǎng)上升子序列是2 4 5 6,長(zhǎng)度為4
???????? 設(shè)a[i]表示原序列,設(shè)DP[i]表示以第i個(gè)數(shù)結(jié)尾的最長(zhǎng)上升序列的長(zhǎng)度,那么很顯然想導(dǎo)出DP[i]的值,需要在DP[k](1<=k<i)中找出滿足a[k]<a[i]最大的一項(xiàng)。假設(shè)第kk項(xiàng)是我們找到的答案,那么第i個(gè)數(shù)就可以接在第kk個(gè)數(shù)之后,成為以第i個(gè)數(shù)結(jié)尾的最長(zhǎng)升序列。如果沒(méi)有找到答案,換言之第i個(gè)數(shù)比前面的數(shù)都要小,那么DP[i]=1,也即生成了從自己開(kāi)始又以自己結(jié)尾的最長(zhǎng)升序列。綜上,我們很容易得出:
???????? 遞推公式:DP[i]=max(DP[k]+1,DP[i])? 1<=k<i
???????? 邊界條件:DP[i]=1?????????????????? 1<=i<=n
???????? 算法復(fù)雜度為O(n^2)
5. 最長(zhǎng)公共子序列
???????? 給定兩個(gè)序列X和Y,稱序列Z是X和Y的公共子序列如果Z既是X的一個(gè)子序列,又是Y的一個(gè)子序列。例如,如果X={a,b,c,b,d,a,b} Y={b,d,c,a,b,a} 那么序列{b,c,a}就是X和Y的一個(gè)公共子序列,但是它并不是X和Y的最長(zhǎng)公共子序列,因?yàn)樗拈L(zhǎng)度為3。而同為X和Y公共子序列的{b,c,b,a},長(zhǎng)度為4,因?yàn)檎也坏介L(zhǎng)度為5或更大的公共子序列,所以X和Y的最長(zhǎng)公共子序列長(zhǎng)度就為4。
???????? 假設(shè)兩個(gè)序列數(shù)組分別為a,b。定義f(i,j)為計(jì)算到a數(shù)組第i個(gè)數(shù)、b數(shù)組第j個(gè)數(shù)時(shí)所得到的最長(zhǎng)公共子序列的長(zhǎng)度。這時(shí)有兩種情況:
???????? 1.假如a[i]=b[j],那么f(i,j)=f(i-1,j-1)+1
???????? 2.假如a[i]!=b[j],那么f(i,j)=max(f(i-1,j),f(i,j-1))
???????? 邊界條件為:f(i,0)=0???? 1<=i<=len(a)
?????????????????????????????? f(0,j)=0???? 1<=j<=len(b)
???????? 算法復(fù)雜度:O(n^2),len(a)表示數(shù)組a的長(zhǎng)度。
總結(jié)
- 上一篇: 全排列(含递归和非递归的解法)
- 下一篇: Python算法:动态规划