HDU6180 Schedule

题意:有许多任务,给你开始时间和结束时间。问最少几台机器可以完成,最小工作时间(每台机器的时间是第一个任务的开始时间到最后一个任务的结束时间)


思路:先来看这么一个问题,多次给一段区间内的数加上某个数,问最大的数是几,比如给[3,5]加上2,最方便的做法是,给开始3打上个记号2,给结束5后的数6,打记号上-2。求一遍前缀和,中间最大的sum就是最大的数。

回到这个问题,最少几台机器,假若某个时间点有m个任务,那需要m台机器。我们给开始时间打记号1,结束时间打记号-1。前缀和中最大的就是最少的机器,和上面的例子很像。这个时间跨度大,不适合开数组,可以每个任务记录两个点,排序(同一时间,结束的点排前面),遍历一遍,开始的点sum+1,结束的点sum-1。机器时间和的话,每次ans更新的时候,就是要开新的机器了,记录下这个点的时间(开始)。结束时间,反着遍历,同样的方式记录。


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<list>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2e5+5;
int t1[maxn],t2[maxn];
struct data
{
	int index,st;
}node[maxn*2];

int cmp(const data &a,const data &b)
{
	if(a.index == b.index)
		return a.st < b.st;
	else
		return a.index < b.index;
}

int main(void)
{
	int T,n;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i = 0; i < n; i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			node[2*i].index = a;
			node[2*i].st = 1;
			node[2*i+1].index = b;
			node[2*i+1].st = 0;
		}
		sort(node,node+2*n,cmp);
		int ans = 0,sum = 0;
		for(int i = 0; i < 2*n; i++)
		{
			if(node[i].st)
			{
				sum++;
				if(sum > ans)
				{
					ans = sum;
					t1[ans] = node[i].index;
				}
			}
			else
				sum--;
		}
		int ans2 = 0;
		sum = 0;
		for(int i = 2*n-1; i >= 0; i--)
		{
			if(!node[i].st)
			{
				sum--;
				if(sum < ans2)
				{
					ans2 = sum;
					t2[-ans2] = node[i].index;
				}
			}
			else
				sum++;
		}
		ll time = 0;
		for(int i = 1; i <= ans; i++)
			time += t2[i] - t1[i];
		printf("%d %lld\n",ans,time);
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值