实验10相容问题

问题:

有n项活动申请使用同一个礼堂,每项活动有一个开始时间和一个截止时间。如果任何两个活动不能同时举行,问如何选择这些活动,从而使得被安排的活动数量达到最多。

解析:

如果我们选择开始时间最早的节目,得不到最优解

如果我们选择时间最短的节目,也无法得到最优解

可以用数学归纳法证明,我们的贪心策略应该是每次选取结束时间最早的活动。

直观上也很好理解,按这种方法选择相容活动为未安排活动留下尽可能多的时间。

所以,我们的贪心策略是按照节目的结束时间排序。

设计(核心代码):

 1 bool cmp(const node &a,const node &b)
 2 {
 3     return a.e<b.e;
 4 }
 5 
 6 sort(p + 1, p + 1 + n, cmp);
 7 int ans = 0, tmp = -1;
 8 for (int i = 1; i <= n; ++i)
 9 {
10     if (p[i].s >= tmp)    ans++, tmp = p[i].e;
11 }

分析:

复杂度:$O( n log(n) )$

源码:

https://github.com/Big-Kelly/Algorithm

 1 #include<bits/stdc++.h>
 2 #include <set>
 3 #include <map>
 4 #include <stack>
 5 #include <cmath>
 6 #include <queue>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstring>
11 #include <iostream>
12 #include <algorithm>
13 
14 #define ll long long
15 #define PLL pair<ll,ll>
16 #define PII pair<int,int>
17 #define bug printf("*********\n")
18 #define FIN freopen("input.txt","r",stdin);
19 #define FON freopen("output.txt","w+",stdout);
20 #define IO ios::sync_with_stdio(false),cin.tie(0)
21 #define ls root<<1
22 #define rs root<<1|1
23 
24 using namespace std;
25 const int inf = 0x3f3f3f3f;
26 const ll Inf = 1e14 + 7;
27 const int maxn = 1e5 + 5;
28 const int mod = 1e9 + 7;
29 
30 struct node
31 {
32     int s, e;
33 }p[maxn];
34 
35 bool cmp(const node& a, const node& b)
36 {
37     return a.e < b.e;
38 }
39 
40 int main()
41 {
42     int n;
43     while (~scanf("%d", &n), n)
44     {
45         for (int i = 1; i <= n; ++i)    scanf("%d %d", &p[i].s, &p[i].e);
46         sort(p + 1, p + 1 + n, cmp);
47         int ans = 0, tmp = -1;
48         for (int i = 1; i <= n; ++i)
49         {
50             if (p[i].s >= tmp)    ans++, tmp = p[i].e;
51         }
52         printf("%d\n", ans);
53     }
54 }
View Code

 

posted @ 2020-05-01 18:23  Big-Kelly  阅读(221)  评论(0编辑  收藏  举报