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 }