Schedule
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 153428/153428 K (Java/Others)Total Submission(s): 456 Accepted Submission(s): 162
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.
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
1 3 1 3 4 6 2 5
Sample Output
2 8
题意:
有n个任务,每个任务有起始时间和结束时间。要你用最少的机器,去完成这些任务,一台机器可以用多次,但只能开一次,关一次。并计算在用最少的机器情况下,机器使用时间的总和
解析:
将每个任务的起始时间和结束时间都放在一条时间轴上,每遇到一个任务开始时间就向前找结束时间最近的未被使用的机器,将这个任务的指向这台机器。
ps,不能同C++交,不然会T,得用G++
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAX = 100000 + 10;
typedef struct {
ll val;
ll id;
int flag;
}Point;
typedef struct {
ll s, e;
}MA;
typedef struct node {
ll val, id;
friend bool operator<(node a, node b)
{
return a.val < b.val;
}
}node;
int n;
Point num[MAX * 2];
int vis[MAX];
MA ma[MAX];
int machine[MAX];
priority_queue<node>q; //存已被使用过但现在未被使用的机器,按照结束时间排序,越晚结束优先级越高
bool cmp(Point p1, Point p2)
{
if (p1.val == p2.val) //若时间相同,先让结束的时间排在前面即先结束在开始
return p1.flag>p2.flag;
return p1.val < p2.val;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
while (!q.empty()) q.pop();
scanf("%d", &n);
for (int i = 1; i <= 2* n; i += 2)
{
ll s, e;
scanf("%lld%lld", &s, &e);
num[i].val = s;
num[i].id = i / 2 + 1;
num[i].flag=0;
num[i + 1].val = e;
num[i + 1].id = i / 2 + 1;
num[i+1].flag=1;
}
sort(num + 1, num + 2 * n + 1, cmp);
memset(vis, 0, sizeof(vis));
int res = 0;
for (int i = 1; i < 2 * n + 1; i++)
{
if (vis[num[i].id] == 0) //任务的开始
{
if (q.empty()) //没有机器可用
{
res++; //加机器
ma[res].s = num[i].val;
machine[num[i].id] = res;
vis[num[i].id] = 1;
}
else //否则取出结束时间最晚的未被使用的机器
{
node x = q.top();
q.pop();
machine[num[i].id] = machine[x.id];
vis[num[i].id] = 1;
}
}
else if (vis[num[i].id] == 1) //任务的结束
{
node a;
a.val = num[i].val;
a.id = num[i].id;
q.push(a);
ma[machine[num[i].id]].e = num[i].val; //更新机器的结束时间
}
}
ll sum = 0;
printf("%d ",res);
for (int i = 1; i <= res; i++)
{
sum += (ma[i].e - ma[i].s);
}
printf("%lld\n", sum);
}
return 0;
}