在《演算法導論》中,講到高階演算法的時候,認為主要有三類,即:動態規劃、貪心演算法和平攤分析。這裡通過乙個經典小例子介紹一下貪心演算法,可以讓我們極速掌握貪心演算法的思想。
例:活動安排問題有n
nn個需要在同一天使用同乙個教室的活動a
1a_1
a1,a
2a_2
a2,⋯
\cdots
⋯,an
a_nan
,教室同一時刻只能由乙個活動使用。每個活動a
ia_i
ai都有乙個開始時間s
is_i
si和結束時間f
if_i
fi 。一旦被選擇後,活動a
ia_i
ai就佔據半開時間區間[si
,fi)
[s_i, f_i)
[si,f
i)。如果[si
,fi]
[s_i,f_i]
[si,f
i]和[sj
,fj]
[s_j,f_j]
[sj,f
j]互不重疊,a
ia_i
ai和a
ja_j
aj兩個活動就可以被安排在這一天。這時也稱這兩個活動是相容的。該問題就是要安排這些活動使得盡量多的活動能不衝突的舉行。例如下圖所示的活動集合a
=a=\
a=,其中各項活動按照結束時間單調遞增排序。
: 活動安排時間表
解題思路:
首先,把各項活動按結束時間單調遞增排序。這樣做是有道理的,因為可以用數學歸納法證明,用貪心演算法求解的時候,最先結束的那個活動一定在解集裡面。具體證明方法在《演算法導論》裡有,這裡略過不提。其實在直觀上也比較好理解,選擇了最早結束的那個活動,可以為未安排的活動留下盡可能多的時間。
其次,我們來考慮貪心策略。上面說過,第乙個活動已經選出來了,就是最早結束的那個活動a
1a_1
a1。那麼第二個活動不妨就選跟它相容的最先開始的活動就行了這個例子中就是a
4a_4
a4,因為s
4>f1
s_4>f_1
s4>f1
。同理,下乙個活動的選取,只要是開始時間大於f
4f_4
f4的最近的乙個就行了,依次類推。這就是貪心的策略,每次都選最近的。
以下是源程式:
#includeusing namespace std;
int greedy(int len, int *s, int *f, bool *flag)
} return 0;
}int main()
; int f[11] = ;
bool flag[11] = ;
flag[0] = true; //由於排序後,第乙個活動肯定能被選中,所以將它的標誌置為"真"。
greedy(11, s, f, flag);
for(int i=0; i<11; i++)
{ if(flag[i])
{ cout在這段程式中,我們用flag[11]來標記每個活動是否被選中。程式執行結果為:1 4 8 11
貪心演算法入門
什麼是貪心呢?貪心演算法 又稱貪婪演算法 是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後...
貪心演算法入門
貪心演算法例題 1 2 取糖果3 輸入 4 15 四箱,能裝的重量為15 4 價值,重量 5100 4 6412 8 7266 7 8591 2 9輸出 101193.0 11 1213 include14 include15 using namespace std 1617 struct cand...
總結 貪心演算法 貪心演算法入門總結
英語 greedy algorithm,又稱貪婪演算法,是一種在每一步選擇中都採取在當前狀態下最好或最優 即最有利 的選擇,從而希望導致結果是最好或最優的演算法。比如在旅行推銷員問題中,如果旅行員每次都選擇最近的城市,那這就是一種貪心演算法。貪心演算法在有最優子結構的問題中尤為有效。最優子結構的意思...