HDU6180 Schedule(贪心)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuxiyulu/article/details/77603333
/*
multiset+贪心
有m个作业,一台机器在同一时间只能运行一个作业,
已知每个作业的起始时间和结束时间,
求出最少要多少个机器以及最少的机器总运行时间
机器开始了就不会停,直到该机器不需要再作业 
*/
#include <cstdio>
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
typedef long long LL;
int n;

struct node
{
    int s;
    int e;
    node() {}
    node(int _s,int _e)
    {
        s=_s;
        e=_e;
    }
    //set默认排序规则
    bool operator <(const node &b)const
    {
        return e<b.e;
    }
} a[maxn];
//初始排序规则
bool cmp1(node x,node y)
{
    if(x.s==y.s)
        return x.e<y.e;
    return x.s<y.s;
}
multiset<node>cnt;
multiset<node>::iterator it;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&a[i].s,&a[i].e);
        }
        sort(a,a+n,cmp1);//初始排序
        cnt.clear();
        cnt.insert(a[0]);
        for(int i=1; i<n; i++)
        {
            //寻找作业中结束时间>当前作业开始时间
            node x=node(0,a[i].s);
            it=cnt.upper_bound(x);
            if(it!=cnt.begin())//不是第一个作业
            {
                it--;//前面一个作业结束时间必定<当前作业开始时间
                //说明,当前作业可以与前一作业共用机器
                int start=it->s;//保存前一作业开始时间
                cnt.erase(it);
                //用前一作业开始时间和当前作业结束时间更新前一作业
                node y=node(start,a[i].e);
                cnt.insert(y);
            }
            else
            {
                cnt.insert(a[i]);//新开一个机器
            }
        }
        LL ans=0;//计算所有机器消耗总时间

        for(it=cnt.begin(); it!=cnt.end(); it++)
        {
            ans+=(it->e-it->s);
        }
        printf("%d %I64d\n",(int)cnt.size(),ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhuxiyulu/article/details/77603333
今日推荐