杭电-6180

来源:互联网 发布:软件开发 外包 杭州 编辑:程序博客网 时间:2024/04/30 16:22

Schedule

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


Problem Description:
There are N schedules, the i-th schedule has start timesi 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 betweentimeend 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 thetimestart 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 integerssi 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个时间表,他们分别有自己的开始时间和结束时间,同时,也有很多机器,时间表上的时间是使用机器的时间,然而,一台机器不能在重复的时间被使用,所以,要完成时间表的任务,可能需要多台机器,题目要求的就是符合要求的最少机器数和相应时间之和。


解题分析:首先,假设机器可以在同一时刻被重复使用,那么最短时间和即为每个时间段之和,但是,现在条件限制机器不能同一时间重复使用,那么必然有机器在执行完一个任务后等待下一个任务的过程,其中的等待时间也要被计入总时间中,而等待时间是下一个时间段的开始时间减去之前时间段的结束时间。所以最短时间可以用每个时间段之和加上等待时间。同时,我们将我每个时间段的开始时间和结束时间拆开,利用结构体存储,用flag = 1标志它是开始时间,flag = 2 标识它为结束时间。对所有时间点进行从小到大排序,用mach记录变化机器数,如果遇左节点,mach++,遇右节点mach--,mach最大值即为最少机器数,同时将结束时间存入栈中,下一时间段的开始时间减去栈顶元素即为等待时间。

演示步骤:

1

3

1 3

2 5

4 6
经sort排序后:

时刻: 1    2    3    4    5   6

flag : 1    1    2    1    2   2


AC代码:

#include<cstdio>#include<algorithm>#include<iostream>#include<stack>using namespace std;struct Nodes{int T;//时间点 int flag;//状态 }node[300000];int cmp(Nodes a , Nodes b){if(a.T != b.T ) return (a.T < b.T);else return (a.flag > b.flag );//如果相等,让状态为结束的点排前 , //因为后面会有开始点状态减去栈中结束状态点,求等待时间 }int main(void){int x;scanf("%d",&x);while(x--){int count;int num = 0;int i;int mach = 0;int ans_mach = 0;long long  ans_sum = 0;//本题数据不用long long会超时; stack<int>endtime;//结束时刻存放数组 scanf("%d",&count);while(!endtime.empty()){endtime.pop(); }for(i=0;i<count;i++){ scanf("%d",&node[num].T); scanf("%d",&node[num+1].T); node[num].flag = 1; node[num+1].flag = 2; ans_sum = ans_sum + ( node[num+1].T - node[num].T); num = num + 2;}sort(node,node + count*2,cmp);for(i=0;i < num ; i++){if(node[i].flag == 1){mach++; if(!endtime.empty()){int t = endtime.top() ;endtime.pop(); ans_sum = ans_sum + (node[i].T - t);//算出等待时间 }}else{mach--;endtime.push(node[i].T); }ans_mach = max(ans_mach,mach); }printf("%d %lld\n",ans_mach,ans_sum);}}



原创粉丝点击