时间限制:1 秒
内存限制:128 兆
-
题目描述:
-
又到毕业季,很多大公司来学校招聘,招聘会分散在不同时间段,小明想知道自己最多能完整的参加多少个招聘会(参加一个招聘会的时候不能中断或离开)。
-
输入:
-
第一行n,有n个招聘会,接下来n行每行两个整数表示起止时间,由从招聘会第一天0点开始的小时数表示。
n <= 1000 。
-
输出:
-
最多参加的招聘会个数。
-
样例输入:
-
3 9 10 10 20 8 15
-
样例输出:
-
2
-
来源:
- 算法之美(面试算法每日一题系列)
-
- 解决方法:贪心算法
- 贪心策略:优先选取 '开始时间'晚于前一个选定的招聘会结束时间 中 '结束时间'最早的招聘会;
- 证明这一策略能保证参加的招聘会个数是最多的
- 设a1的结束时间是所有序列中最早的,那根据前面的假设应该有
- a1 a2 a3 a4.........an是所有可能的序列中最长的 序列程度为an= n;
- 设B的结束时间比a1晚,那么当我们用B替换a1的位置时候
- 会产生两种情况
- 一 :当B的结束时间早于a2的开始时间时,序列为B a2 a3......an 序列程度Bn = n;
-
二:当B的结束时间晚于a2(a3 a4也可能受影响)的开始时间时,序列为B (a2)
a3......an 序列程度Bn<n;
- 这样我们可以求证:Bn <= an;
- 贪心策略得证;
- 代码如下
-
#include <iostream> #include<cstdio> #include <algorithm> using namespace std; struct meet { int s; int e; }; int cmp(meet a, meet b) { return a.e<b.e; } meet m[1001]; int main() { int n; while(cin>>n) { if(n==0) continue; int i = 0; for(i=1; i<=n; i++) { scanf("%d %d",&m[i].s,&m[i].e); } sort(m+1,m+n+1,cmp);//升序排序 贪心策略 int end=m[1].e; int maxl = 1; for(i=2;i<=n;i++) { if(m[i].s >= end) { end = m[i].e; maxl++; } } cout<<maxl<<endl; } } /************************************************************** Problem: 1463 User: hrdjmax2 Language: C++ Result: Accepted Time:10 ms Memory:1528 kb ****************************************************************/
-