首页 > 代码库 > 活动选择

活动选择

活动选择
学校在最近几天有n个活动,这些活动都需要使用学校的大礼堂,在同一时间,礼堂只能被一个活动使。由于有些活动时间上有冲突,学校办公室人员只好让一些活动放弃使用礼堂而使用其他教室。   
现在给出n个活动使用礼堂的起始时间begini和结束时间endi(begini < endi),请你帮助办公室人员安排一些活动来使用礼堂,要求安排的活动尽量多。
【输入】 第一行一个整数n(n<=1000);  
接下来的n行,每行两个整数,第一个begini,第二个是endi(begini< endi <=32767)
【输出】 输出最多能安排的活动个数。
【样例输入】
  11
  3 5
  1 4
  12 14
  8 12
  0 6
  8 11
  6 10
  5 7
  3 8
  5 9
  2 13
【样例输出】
   4

分析:

? 算法模型:给n个开区间(begini,endi), 选择尽量多的区间, 使得两两不交。
? 做法: 首先按照end1<=end2<…<=endn的顺序排序,依次考虑各个活动, 如果没有和已经选择的活动冲突, 就选; 否则就不选。
? 正确性: 如果不选end1, 假设第一个选择的是endi,则如果endi和end1不交叉则多选一个end1更划算; 如果交叉则把endi换成end1不影响后续选择。

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 struct section
 4 {
 5     int id;
 6     int begin;
 7     int end;
 8     int flag;//是否被选中 
 9 };
10 int cmp(const void *a,const void *b);
11 int main()
12 {
13     freopen("act.in","r",stdin);
14     freopen("act.out","w",stdout);
15     struct section a[1005];
16     int n,i,lastEnd;
17     int count=0;
18     
19     scanf("%d",&n);
20     for(i=0;i<n;i++)
21     {
22         scanf("%d%d",&a[i].begin,&a[i].end);
23         a[i].id=i+1;
24         a[i].flag=0;
25     }
26     
27     qsort(a,n,sizeof(struct section),cmp);
28     
29     lastEnd=-1;
30     for(i=0;i<n;i++)
31     {
32         if(a[i].begin>=lastEnd) 
33         {
34             count++;
35             lastEnd=a[i].end;
36             a[i].flag=1;
37         }
38     }
39     /*
40     for(i=0;i<n;i++)
41     {
42         if(a[i].flag=1)
43             printf("%d\n",a[i].id);
44     }*/
45     
46     printf("%d\n",count);
47     return 0;
48 }
49 int cmp(const void *a,const void *b)
50 {
51     int ans= ((struct section *)a)->end -((struct section *)b)->end;
52     if(ans>0) return 1;
53     else if(ans<0) return -1;
54     else return 0;
55 }

 

活动选择