活動選擇問題 動態規劃 貪心演算法

2022-02-18 02:47:54 字數 2151 閱讀 9236

問題描述:

設有n個活動的集合e=,其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。每個活動i都有乙個要求使用該資源的起始時間si和乙個結束時間fi,且si 。

從圖中可以看出s中共有11個活動,最大的相互相容的活動子集為:和。

2、動態規劃解決過程

(1)活動選擇問題的最優子結構

定義子問題解空間sij是s的子集,其中的每個獲得都是互相相容的。即每個活動都是在ai結束之後開始,且在aj開始之前結束。

為了方便討論和後面的計算,新增兩個虛構活動a0和an+1,其中f0=0,sn+1=∞。

結論:當i≥j時,sij為空集。

如果活動按照結束時間單調遞增排序,子問題空間被用來從sij中選擇最大相容活動子集,其中0≤i<j≤n+1,所以其他的sij都是空集。

最優子結構為:假設sij的最優解aij包含活動ak,則對sik的解aik和skj的解akj必定是最優的。

通過乙個活動ak將問題分成兩個子問題,下面的公式可以計算出sij的解aij。

(2)乙個遞迴解

設c[i][j]為sij中最大相容子集中的活動數目,當sij為空集時,c[i][j]=0;當sij非空時,若ak在sij的最大相容子集中被使用,則則問題sik和skj的最大相容子集也被使用,故可得到c[i][j] = c[i][k]+c[k][j]+1。

當i≥j時,sij必定為空集,否則sij則需要根據上面提供的公式進行計算,如果找到乙個ak,則sij非空(此時滿足fi≤sk且fk≤sj),找不到這樣的ak,則sij為空集。

c[i][j]的完整計算公式如下所示:

親測**:

1 #include 2

#define max_size 10010

3int

s[max_size];

4int

f[max_size];

5int

c[max_size][max_size];

6int

ret[max_size][max_size];78

using

namespace

std;910

void dp_selectof(int *s,int *f,int n,int c[max_size],int

ret[max_size])

1127}28

}29}30

}3132int

main()

3346

dp_selectof(s,f,n,c,ret);

47 printf("

最大子集的個數=%d\n

",c[1][n]+2

);48

return0;

49 }

view code

下面是貪心法的**:

1 #include 2

#define max_size 10010

3int

s[max_size];

4int

f[max_size];

5int

ret[max_size];

6int

c[max_size][max_size];

7using

namespace

std;89

void greedy_activity_selector(int *s,int *f,int n,int *ret)

1020}21

intmain()

2237

greedy_activity_selector(s,f,n,ret);

38for(i=0;i<=n;i++)

3943 printf("\n"

);44

}45 }

view code

活動選擇問題 動態規劃 貪心演算法

問題描述 有乙個需要使用每個資源的n個活動組成的集合s 資源每次只能由乙個活動使用。每個活動ai都有乙個開始時間和結束時間,且 0 si fi 無窮 一旦被選擇後,活動ai就佔據半開時間區間 si,fi 如果 si,fi 和 sj,fj 互不重疊,則稱兩個活動是相容的。該問題就是要找出乙個由互相相容...

動態規劃 貪心演算法 活動選擇問題 收藏

問題描述和分析 演算法導論 p222 16.1活動選擇問題.這裡給出了動態規劃和貪心演算法兩種演算法的 view plaincopy to clipboardprint?動態規劃解法 include using namespace std const int n 11 int s n 2 int f...

活動選擇問題(動態規劃和貪心演算法)

有乙個由n個活動組成的集合s 1.這些活動使用同乙個資源,而這個資源在某一時刻只供乙個活動使用 2.每個活動都有乙個開始和結束時間si fi 如果被選中,則任務ai發生在半開時間區間 si,fi 3.如果兩個活動ai和aj不重疊,則稱兩個活動相容 活動選擇問題,希望選出乙個最大相容活動集 假設活動已...