活动安排问题

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>

using namespace std;

const int maxn = 10000 + 1;

typedef struct
{
    int start;
    int over;
}point;

point p[maxn];

const int cmp(const  point a, const  point b)
{
    return a.over <= b.over;
}

int main()
{
    int n;
    while (cin >> n)
    {
        memset(p, 0, sizeof(p));
        for (int i = 0;i<n;i++)
            cin >> p[i].start >> p[i].over;
        sort(p, p + n, cmp);
        int cnt = 1;
        for (int i = 0;i<n;i++)
        {
            for (int j = i + 1;j<n;j++)
            {
                if (p[i].over <= p[j].start)
                {
                    i = j;
                    cnt++;
                    continue;
                }
            }
        }
        cout << cnt << endl;
    }
    return 0;
}
有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动?

分析: 我们就是想提高教室地利用率,尽可能多地安排活动。
考虑容易想到的几种贪心策略:

(1) 开始最早的活动优先,目标是想尽早结束活动,让出教室。
然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动。例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排除它外的4个活动。

(2) 短活动优先, 目标也是尽量空出教室。但是不难构造如下反例: [0,5) [5,10) [3, 7), 这里[3,7)最短,但如果我们安排了[3,7),其它两个无法安排了。但是最优解显然是安排其它两个,而放弃[3,7),可见这个贪心策略也是不行的。
 

最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
 
输入

第1行:1个数N,线段的数量(2 <= N <= 10000)
第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9)
输出
 
输出最多可以选择的线段数量。
 
输入示例

3
1 5
2 3
3 6

输出示例

2
posted @ 2016-05-19 14:32  邹大佳  阅读(188)  评论(0编辑  收藏  举报