hdu 6180 Schedule (贪心)

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.
 

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值