活动安排问题--贪心算法
活動(dòng)安排問(wèn)題就是要在所給的活動(dòng)集合中選出最大的相容活動(dòng)子集合,是可以用貪心算法有效求解的很好例子。該問(wèn)題要求高效地安排一系列爭(zhēng)用某一公共資源的活動(dòng)。貪心算法提供了一個(gè)簡(jiǎn)單、漂亮的方法使得盡可能多的活動(dòng)能兼容地使用公共資源。
設(shè)有n個(gè)活動(dòng)的集合E={1,2,…,n},其中每個(gè)活動(dòng)都要求使用同一資源,如演講會(huì)場(chǎng)等,而在同一時(shí)間內(nèi)只有一個(gè)活動(dòng)能使用這一資源。每個(gè)活動(dòng)i都有一個(gè)要求使用該資源的起始時(shí)間si和一個(gè)結(jié)束時(shí)間fi,且si <fi 。如果選擇了活動(dòng)i,則它在半開(kāi)時(shí)間區(qū)間[si, fi]內(nèi)占用資源。若區(qū)間[si, fi]與區(qū)間[sj, fj]不相交,則稱活動(dòng)i與活動(dòng)j是相容的。也就是說(shuō),當(dāng)si≥fj或sj≥fi時(shí),活動(dòng)i與活動(dòng)j相容。
由于輸入的活動(dòng)以其完成時(shí)間的非減序排列,所以算法greedySelector每次總是選擇具有最早完成時(shí)間的相容活動(dòng)加入集合A中。直觀上,按這種方法選擇相容活動(dòng)為未安排活動(dòng)留下盡可能多的時(shí)間。也就是說(shuō),該算法的貪心選擇的意義是使剩余的可安排時(shí)間段極大化,以便安排盡可能多的相容活動(dòng)。
此算法的效率極高。當(dāng)輸入的活動(dòng)已按結(jié)束時(shí)間的非減序排列,算法只需O(n)的時(shí)間安排n個(gè)活動(dòng),使最多的活動(dòng)能相容地使用公共資源。如果所給出的活動(dòng)未按非減序排列,可以用O(nlogn)的時(shí)間重排。
貪心算法并不總能求得問(wèn)題的整體最優(yōu)解。但對(duì)于活動(dòng)安排問(wèn)題,貪心算法卻總能求得的整體最優(yōu)解,即它最終所確定的相容活動(dòng)集合A的規(guī)模最大。這個(gè)結(jié)論可以用數(shù)學(xué)歸納法證明。
算法模版:
template <class Type> void GreedySelector(int n,Type s[],Type f[],bool A[]) {A[1] = true;int j=1;for(int i=2;i<=n;i++){if(s[i]>=f[j]){A[i] = true;j=i;}elseA[i] = false;} }?
?
應(yīng)用實(shí)例:
問(wèn)題描述:
Problem Description “今年暑假不AC?” “是的。” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...”確實(shí)如此,世界杯來(lái)了,球迷的節(jié)日也來(lái)了,估計(jì)很多ACMer也會(huì)拋開(kāi)電腦,奔向電視了。 作為球迷,一定想看盡量多的完整的比賽,當(dāng)然,作為新時(shí)代的好青年,你一定還會(huì)看一些其它的節(jié)目,比如新聞聯(lián)播(永遠(yuǎn)不要忘記關(guān)心國(guó)家大事)、非常6+7、超級(jí)女生,以及王小丫的《開(kāi)心辭典》等等,假設(shè)你已經(jīng)知道了所有你喜歡看的電視節(jié)目的轉(zhuǎn)播時(shí)間表,你會(huì)合理安排嗎?(目標(biāo)是能看盡量多的完整節(jié)目)Input 輸入數(shù)據(jù)包含多個(gè)測(cè)試實(shí)例,每個(gè)測(cè)試實(shí)例的第一行只有一個(gè)整數(shù)n(n<=100),表示你喜歡看的節(jié)目的總數(shù),然后是n行數(shù)據(jù),每行包括兩個(gè)數(shù)據(jù)Ti_s,Ti_e (1<=i<=n),分別表示第i個(gè)節(jié)目的開(kāi)始和結(jié)束時(shí)間,為了簡(jiǎn)化問(wèn)題,每個(gè)時(shí)間都用一個(gè)正整數(shù)表示。n=0表示輸入結(jié)束,不做處理。Output 對(duì)于每個(gè)測(cè)試實(shí)例,輸出能完整看到的電視節(jié)目的個(gè)數(shù),每個(gè)測(cè)試實(shí)例的輸出占一行。Sample Input 12 1 3 3 4 0 7 3 8 15 19 15 20 10 15 8 18 6 12 5 10 4 14 2 9 0Sample Output 5代碼:
#include <stdio.h> #include <math.h> #include <stdlib.h> typedef struct {int s;int e; }node; int cmp(const void *a,const void *b) {return ((node *)a)->e-((node *)b)->e; } int main() {int n,i,j,c;node a[1000];while(scanf("%d",&n),n){for(i=0;i<n;i++)scanf("%d%d",&a[i].s,&a[i].e);qsort(a,n,sizeof(a[0]),cmp); //按結(jié)束時(shí)間升序排列c=1;i=0;for(j=1;j<n;j++){if(a[j].s>=a[i].e) {c++;i=j;}}printf("%d\n",c);}return 0; }總結(jié)
以上是生活随笔為你收集整理的活动安排问题--贪心算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 双数组 实现 Trie
- 下一篇: 网站提速-页面静态化(2)