贪心法解决区间调度问题+快速排序

来源:互联网 发布:浏览器 网络连接错误 编辑:程序博客网 时间:2024/05/31 00:39

                                                         礼堂

学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。

输入:第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)

输出:对于每一组输入,输出最多能够安排的活动数量。每组的输出占一行。

样例输入:

2

2

1 10

10 11

3

1 10

10 11

11 20

样例输出:

1

2

提示:如果上一个活动在t时间结束,下一个活动最早应该在t+1时间开始


//此题采用贪心法解决,贪心法总是选取当前最优解,在此题中,先按照结束时间进行活动排序,然后开始依次寻找相容性最大的活动集合(直至无法找到下一个可以进行的活动,结束寻找)

//需要特别注意的是,如果选用效率较低的排序方法,如冒泡排序或者选择排序,时间复杂度为O(n*n),就会发生超时,所以采用快排

代码如下,欢迎指正:

#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
typedef struct{int s,e;}Data;
Data time[maxn];
void quick_sort(int left,int right)
{
    if(left>right) return;
    int i,j,temp;
    Data temptime;
    temp=time[left].e;
    temptime=time[left];
    i=left;
    j=right;
    while(i!=j)
    {
        while(time[j].e>=temp&&i<j)
            j--;
        while(time[i].e<=temp&&i<j)
            i++;
        swap(time[i],time[j]);
    }
    time[left]=time[i];
    time[i]=temptime;
    quick_sort(left,i-1);
    quick_sort(i+1,right);
}
int main()
{
    int n;
    scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            int m;
            scanf("%d",&m);
            for(int i=0;i<m;i++)
                scanf("%d%d",&time[i].s,&time[i].e);
            quick_sort(0,m-1);
            int t=1;
            for(int i=0;i<m-1;)
                {
                    int n=0;
                    for(int j=i+1;j<m;j++)
                        if(time[i].e<time[j].s)
                          {
                            i=j;
                            t++;
                            n++;
                            break;
                          }
                          if(!n) break;
                }
                cout<<t<<endl;
        }
    return 0;
}

然而,当接触到pair时,代码就会变得更为简洁,pair和sort联合起来使用,代码大大简化

#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=10000+5;
typedef pair<int,int>PII;
PII p[maxn];
int main()
{
    int n;
    scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            int m;
            scanf("%d",&m);
            for(int i=0;i<m;i++)
                scanf("%d%d",&p[i].second,&p[i].first);//按照结束时间进行活动排序
            sort(p,p+m);
   //t为最后所选活动的结束时间,下面的方法不是通用方法,当开始时间可以为0时,下面的寻找方法是错误的,开始时间为0时,它无法完成t的初始赋值
          /*  int t=0,ans=0;
            for(int i=0;i<m;i++)
                if(t<p[i].second) {
                                   ans++;
                                   t=p[i].first;
                                   }
            cout<<ans<<endl;     */

//通用方法如下

       int ans=1,t=p[0].first;

       for(int i=1;i<m;i++)

             if(t<p[i].second) {

                                         ans++;

                                         t=p[i].first;

                                          }

          cout<<ans<<endl;
        }
    return 0;
}