活动选择

活动选择
学校在最近几天有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 }

 

活动选择问题是经典的动态规划问题,可以使用贪心算法或动态规划算法解决。下面给出一个使用动态规划算法解决活动选择问题的 Python 代码示例: ```python def max_activities(activities, start, finish): # 按结束时间排序 sorted_activities = sorted(zip(finish, activities)) n = len(activities) dp = [0] * n dp[0] = 1 for i in range(1, n): dp[i] = max(dp[j] for j in range(i) if sorted_activities[j][0] <= sorted_activities[i][1]) + 1 return dp[n-1] # 示例 activities = ['A', 'B', 'C', 'D', 'E', 'F'] start = [1, 3, 0, 5, 8, 5] finish = [2, 4, 6, 7, 9, 9] print(max_activities(activities, start, finish)) # 输出 4,即选择 A、B、D、F 这 4 个活动 ``` 在上面的代码中,`max_activities` 函数接受三个参数,分别是 `activities`、`start` 和 `finish`。其中,`activities` 是一个列表,表示各个活动的名称;`start` 是一个列表,表示各个活动的开始时间;`finish` 是一个列表,表示各个活动的结束时间。 在函数中,首先将所有活动按照结束时间排序,然后使用一个 `dp` 列表存储每个活动作为最后一个活动时,能够选择的最多活动数量。初始时,第一个活动的 `dp` 值为 1,然后从第二个活动开始遍历,对于每个活动,找到所有结束时间早于它的活动,计算它们的 `dp` 值,并取最大值加 1 就是当前活动的 `dp` 值。最终,`dp` 列表中的最大值即为能够选择的最多活动数量。 需要注意的是,上面的代码中并没有输出具体选哪些活动,如果需要输出具体解,可以再使用一些技巧进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值