動態規劃演算法之課程安排
問題:教務處給某乙個教室安排課程,有很多老師都想來這個教室教授他們各自的課。假如第
i 位老師講的第ai
門課程,課程開始時間si
,結束時間為fi
。那麼教務處的老師就要利用這個時間如何安排課程,使得來這間教室上課的人數最多?
舉個例子:
最底下為時間軸,每條黑線代表一門課程。我們用
w 表示該課程有多少學生。我們看教務處安排最多有多少人來該教室上課。
分析:課程太多我無從下手。看能不能分成子問題求解。先dandc,然後dp。我們把求解過程看出一系列決策過程,在每個步驟我們都要選一門課程。假裝我們已經拿到了最優決策方案,我現在就想知道最優解中最後乙個決策到底是什麼?也就是an
你是選了還是木有選?假如選擇了,那a8
肯定不能選。為啥,時間衝突啦。那剩下的問題就是從其他幾門課選最優的。如下圖所示:
也就是說我們選擇了一門課程之後,問題規約成乙個7門課程安排問題,這樣我們繼續往下把問題變小。此外我們剛才是選啦a9
,要是我們剛剛沒選a9
,那怎麼辦呢?顯然從其他8門課程選擇,不管時間是否衝突。如下圖所示:
這裡插一句非常關鍵話:我們一開始把課程按結束時間排好序。
現在我們就可以寫出遞迴表示式了: op
t(n)
=max
⎧⎩⎨o
pt(p
re(i
))+w
iopt
(i−1
)
此處,其中pre(i)是表示第i門課程開始時已經結束的課程。
具體實現過程如下:
#include
struct coursecourse[9];
void init_course_information()
int max(int a,int b)
int pre(int n)
}return result;
}int scheduling_dp(int n)
else
}void main()
2. 貪心演算法之課程安排問題:問題:現在我們假設每個課程的人數都為1。我們的任務還是和原來一樣,選擇一些不衝突的課程,讓來該教室上課的學生人數最多,怎麼辦?當然上面的動態演算法我們可以繼續使用。但dp來解決這個問題就感覺有點慢了。為啥?還有更快的演算法?問題如下圖所示:
分析:我們來審視這個問題。原來的性質依然存在。而且還多了個性質,那就是貪心選擇的性質。它又是什麼呢?回到問題本身,可以這麼描述,假如課程ai
下課最早,那麼它肯定會出現在最優解。首先我們選最早下課的課程a1
,接下來的問題就是在藍色的方框裡面選最優解就行,如此規約。
這個時候,我們寫出遞迴表示式如下: op
t(n)
=max
⎧⎩⎨o
pt(p
re(i
))+w
iopt
(i−1
) 此處,其中pre(i)是表示第i門課程開始時已經結束的課程。
具體實現過程如下:
#include
struct coursecourse[9];
void init_course_information()
int scheduling_greedy(int n)
}return num;
}void main()
result=scheduling_greedy(n-1);
printf("最多上課人數=%d\n",result);
}
總結:動態規劃演算法和貪心演算法都是用來求解優化問題。最優子結構性質二者都要用到,但是貪心演算法還要用到貪心性質,這個不同問題,貪心性質不同。此外,每個貪心演算法的背後幾乎都有乙個動態規劃演算法。上面的這兩個問題都可用動態規劃求解。但第乙個問題卻不能用貪心演算法求解。動態規劃演算法需要在每乙個決策步列舉所有的解空間中的解,而貪心演算法不需要,依賴區域性最優解來做決策。 動態規劃與貪心演算法
1.動態規劃演算法 在解決最優解時我們用到的兩個演算法,貪心與動態規劃演算法,接下來我根據自己的理解解釋兩者的差異之處。貪心會怎樣做,動態規劃又會怎樣做?我的了解,貪心演算法是自頂向下,及每一步向下都取最大值,但得到的是最優解嗎?如圖顯然不是。接下來我會逐一跟大家演示。動態規劃解法,從小規模來看是否...
貪心演算法 and 動態規劃
動態規劃dynamic programming 貪心演算法,又名貪婪法,是尋找最優解問題的常用方法 步驟1 從某個初始解出發 步驟2 採用迭代的過程,當可以向目標前進一步時,就根據區域性最優策略,得到一部分解,縮小問題規模 步驟3 將所有解綜合起來。假設你開了間小店,不能電子支付,錢櫃裡的貨幣只有 ...
動態規劃和貪心演算法
動態規劃 通過組合子問題的解來求解原問題,常用來求解最優化問題。常用來解決以下幾類問題,但不是說遇到類似問題必須用動態規劃來解決,可以往這方面去想 1.計數問題,如有多少種方式走到右下角,有多少種方法選出k個數使得和是sum 2.求最大最小值,如從左上角走到右下角路徑的最大數字和 3.求存在性,如取...