View Code
1 #include<IOSTREAM.H> 2 #include <IOMANIP.H> 3 4 /************************************************************************/ 5 /* 6 活动选择问题:对几个互相竞争的活动进行调度,它们都要求以独占的方式使用某一公共资源 7 。调度的目标是找出一个最大的相互兼容的活动集合。假设有一个需要使用某一资源的n个活动 8 组成的集合S={a1,a2,a3,...,an}。该资源一次只能被一个活动占用。每个活动ai有个开始时间 9 si和结束时间fi,且0<=si<fi。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果区间 10 [si,fi)和[sj,fj)互不重叠,称活动ai,aj是兼容的。活动选择问题就是要选择出一个由互不 11 兼容的问题组成的最大子集合。 12 思路: 13 把活动安结束时间由小到大排序,假设集合S已经排好序 14 map[n]表示有n个活动时最大子集合元素的个数 15 16 假设有i个活动,最大子集合中可能包含第i个活动,也可能不包含 17 (1)如果最大子集合中不包含第i个活动,则 map[i]=map[i-1],即其和有i-1个活动时拥有相同 18 的最大子集合。 19 (2)如果最大子集合中包含第i个活动,则在第i个活动开始时间之后结束都不会包含在该最大 20 集合中,map[i]=map[k]+1;k是从第i-1到第0个活动结束的时间小于或等于第i个活动的开始时间的最大值 21 */ 22 /************************************************************************/ 23 24 void main() 25 { 26 int E[]={0,4,5,6,7,8,9,10,11,12,13,14};//结束时间 27 int B[]={0,1,3,0,5,3,5, 6, 8, 8, 2,12};//开始时间 28 int M[]={0,2,5,3,4,7,6, 2, 5, 4, 3, 1};//收益 29 int num[12]={0};//num[i]表示I件事中最大收益 30 for(int i=1;i<12;i++) 31 { 32 int temp1=num[i-1];//表示不包含第I个事件时,最大收益 33 int temp2=0; 34 for(int k=i-1;k>=0;k--)//如果包含 35 { 36 if(B[i]>=E[k]) 37 { 38 temp2=num[k]+M[i]; 39 break; 40 } 41 } 42 num[i]=temp1>temp2?temp1:temp2; 43 } 44 for(i=1;i<12;i++) 45 { 46 cout<<setw(3)<<num[i]; 47 } 48 cout<<endl; 49 //求出最大子集合中包含活动的序号 50 i=11; 51 while(i>0) 52 { 53 if (num[i]>num[i-1]) 54 { 55 cout<<setw(3)<<i; 56 for(int k=i-1;k>=0;k--)//如果包含 57 { 58 if(B[i]>=E[k]) 59 { 60 i=k; 61 break; 62 } 63 } 64 } 65 else 66 { 67 i=i-1; 68 } 69 } 70 cout<<endl; 71 }
View Code