有乙個由n個活動組成的集合s =
1. 這些活動使用同乙個資源,而這個資源在某一時刻只供乙個活動使用
2. 每個活動都有乙個開始和結束時間si/fi;如果被選中,則任務ai發生在半開時間區間[si, fi)
3. 如果兩個活動ai和aj不重疊,則稱兩個活動相容
活動選擇問題,希望選出乙個最大相容活動集
假設活動已經按結束時間遞增排好序
最優子結構
sij表示在ai結束之後,aj開始之前結束之前的活動集合;aij表示sij的乙個最大相容活動集
假設aij包含ak,
則得到兩個子問題
,尋找sik以及skj的最大相容活動集
用c[i, j]表示集合sij的最優解的大小,則可得遞迴式:c[i, j] = c[i, k] + c[k, j] + 1
從而實際上
c[i, j] = 0 if sij = 空集
max ak屬於sij
活動選擇問題的另乙個性質
,使得無須求解所有子問題就可以選擇出乙個活動加入到最優解;選擇的標準為,選出活動後剩下的資源應能被盡量多的其他任務所用
【選擇最早結束的活動】
定理可以證明:任意非空子問題sk,am是sk中結束時間最早的活動,則am在sk的某個最大相容活動子集中【
假設乙個最大相容活動子集ak,用am替代ak中最早結束的活動得到ak',依然是最大相容活動子集
】——>貪心演算法,自頂向下的設計,做出乙個選擇,然後求解剩下的那個子問題,而不像動態規劃自底向上地求解很多子問題,然後再做出選擇
假設已經按照活動結束時間排好序
遞迴貪心演算法:
recursive-activity-selector(s, f, k, n)
// s表示活動的開始時間陣列;f表示結束時間陣列;k表示上乙個選中的活動,初始為0【引入a[0],其結束時間為0】;n為問題規模
m = k + 1
while(m<=n && s[m] < f[k])
//活動必須在活動集合中;且其開始時間必須比上乙個活動的結束時間晚
m = m + 1
if m<=n
return a[m] 並上
recursive-activity-selector(s, f, m, n)
else
return 空集
迭代貪心演算法:(通常「尾遞迴」的演算法都可以很直接的轉化為迭代形式)
greedy-activity-selector(s, f)
n = s.length
a =
k = 1
for m = 2 to n
if(s[m] >= f[k])
a = a 並上
k = m
return a
活動選擇問題 動態規劃 貪心演算法
問題描述 有乙個需要使用每個資源的n個活動組成的集合s 資源每次只能由乙個活動使用。每個活動ai都有乙個開始時間和結束時間,且 0 si fi 無窮 一旦被選擇後,活動ai就佔據半開時間區間 si,fi 如果 si,fi 和 sj,fj 互不重疊,則稱兩個活動是相容的。該問題就是要找出乙個由互相相容...
活動選擇問題 動態規劃 貪心演算法
問題描述 設有n個活動的集合e 其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。每個活動i都有乙個要求使用該資源的起始時間si和乙個結束時間fi,且si 從圖中可以看出s中共有11個活動,最大的相互相容的活動子集為 和。2 動態規劃解決過程 1 活動選擇問題的...
動態規劃 貪心演算法 活動選擇問題 收藏
問題描述和分析 演算法導論 p222 16.1活動選擇問題.這裡給出了動態規劃和貪心演算法兩種演算法的 view plaincopy to clipboardprint?動態規劃解法 include using namespace std const int n 11 int s n 2 int f...