Hdu 6180 Schedule【贪心】

来源:互联网 发布:淘宝 韩国二手钢琴 编辑:程序博客网 时间:2024/05/16 06:54

Schedule

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 153428/153428 K (Java/Others)
Total Submission(s): 539    Accepted Submission(s): 204


Problem Description
There are N schedules, the i-th schedule has start time si and end time ei (1 <= i <= N). There are some machines. Each two overlapping schedules cannot be performed in the same machine. For each machine the working time is defined as the difference between timeend and timestart , where time_{end} is time to turn off the machine and timestart is time to turn on the machine. We assume that the machine cannot be turned off between the timestart and the timeend
Print the minimum number K of the machines for performing all schedules, and when only uses K machines, print the minimum sum of all working times.
 

Input
The first line contains an integer T (1 <= T <= 100), the number of test cases. Each case begins with a line containing one integer N (0 < N <= 100000). Each of the next N lines contains two integers si and ei (0<=si<ei<=1e9).
 

Output
For each test case, print the minimum possible number of machines and the minimum sum of all working times.
 

Sample Input
131 34 62 5
 

Sample Output
2 8

题目大意:


给出N个执行任务的区间【L,R),问你最少用多少台机器能够完成任务,并且输出最少的每台机器的工作时间总和。

一台机器如果开启了,再关闭之后就不能开启了。


思路:


我们知道,区间覆盖数最大的值,就是我们使用的最少机器数量。


接下来考虑如何搞这个时间总和:

①如果我们能够知道一台机器的开启时间和结束时间就很容易搞定这个问题了、

②那么设定L【i】,R【i】分别表示第i台机器的开启时间和关闭时间。

③那么我们将所有任务的区间的点按照从小到大排序,那么我们从左向右扫,每遇到一个任务起点,sum++,遇到一个任务终点,sum--.我们知道,当sum>ans的时候,我们就需要开启一台新的机器,并且更新ans=sum;这样我们就能够很容易处理出L【i】;

④那么反过去,我们从后向前扫,遇到一个任务终点,sum++,遇到一个任务起点,sum--,我们知道,当sum>ans的时候,我们就相当于关闭了一台机器,并且更新ans=sum

这样我们能够很容易处理出R【i】;

⑤最终的时间总和就是ΣR【i】-L【i】


Ac代码:

#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;struct node{    int op,x;}a[250000];int L[2500000];int R[2500000];int Sum[2500000];int cmp(node a,node b){    if(a.x==b.x)return a.op<b.op;    return a.x<b.x;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        int cnt=0;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            int x,y;scanf("%d%d",&x,&y);            a[cnt].x=x;            a[cnt++].op=1;            a[cnt].x=y;            a[cnt++].op=-1;        }        int ans=0;        int cont=0;        int sum=0;        sort(a,a+cnt,cmp);        for(int i=0;i<cnt;i++)        {            sum+=a[i].op;            if(sum>ans)            {                ans=sum;                L[ans]=a[i].x;            }        }        ans=sum=0;        for(int i=cnt-1;i>=0;i--)        {            sum-=a[i].op;            if(sum>ans)            {                ans=sum;                R[ans]=a[i].x;            }        }        __int64 output=0;        for(int i=1;i<=ans;i++)        {            output+=R[i]-L[i];        }        printf("%d %I64d\n",ans,output);    }}