1. 程式人生 > >【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 貪心+堆

【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 貪心+堆

需要 -s push tor 打開 研究員 sample while color

題目描述

佩內洛普是新建立的超級計算機的管理員中的一員。 她的工作是分配工作站給到這裏來運行他們的計算研究任務的研究人員。 佩內洛普非常懶惰,不喜歡為到達的研究者們解鎖機器。 她可以從在她的辦公桌遠程解鎖這些機器,但她並不覺得這卑賤的任務配得上她,所以她決定忽略安全指南偷偷懶。她可以直接地要求,研究者在他們離開時不用鎖定自己的工作站,然後把未在使用且還在未鎖定狀態的工作站分配給新來的研究人員。 這樣,她只需要為每一個工作站第一次被使用所屬的研究員解鎖工作站,這對佩內洛普的工作來說是一個巨大的改善。 不幸的是,如果一個工作站在未鎖定且沒被使用的狀態下超過m分鐘,會自動鎖定自己,佩內洛普必須為使用它的下一個研究員再次打開它。 鑒於抵達和離開的研究人員的確切時間表,你可以告訴佩內洛普,要求研究者在離開時不鎖定工作站最多可以使她節約多少次的解鎖工作。你可以認為這兒總是有足夠的可用工作站。

輸入

一行兩個整數n (1≤n≤300000) 研究員的數量n,以及 m (1≤m≤100000000) 工作站在未鎖定且沒被使用的狀態下超過m分鐘會自動鎖定。 下面的n行,每一行兩個整數a與s (1≤a,s≤100000000) 表示一個研究員在第a分鐘時到達以及待了s分鐘後離開。

輸出

輸出研究者在離開時不鎖定工作站最多可以使她節約多少次解鎖工作。

樣例輸入

5 10
2 6
1 2
17 7
3 9
15 6

樣例輸出

3


題解

貪心+堆

語文題慢慢讀吧。。。

讀完題後發現貪心策略顯然:把所有區間按照左端點從小到大排序,對於一個區間,選擇結束時間最早的區間作為上一個,答案+1;如果不存在則新建一個。

拿堆維護一下即可。

時間復雜度 $O(n\log n)$

#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
struct data
{
	int l , r;
	bool operator<(const data &a)const {return l < a.l;}
}a[300010];
priority_queue<int> q;
inline char nc()
{
	static char buf[100000] , *p1 , *p2;
	return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
}
inline int read()
{
	int ret = 0; char ch = nc();
	while(!isdigit(ch)) ch = nc();
	while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ ‘0‘) , ch = nc();
	return ret;
}
int main()
{
	int n = read() , m = read() , i , ans = 0;
	for(i = 1 ; i <= n ; i ++ ) a[i].l = read() , a[i].r = a[i].l + read();
	sort(a + 1 , a + n + 1);
	for(i = 1 ; i <= n ; i ++ )
	{
		while(!q.empty() && -q.top() + m < a[i].l) q.pop();
		if(!q.empty() && -q.top() <= a[i].l) ans ++ , q.pop();
		q.push(-a[i].r);
	}
	printf("%d\n" , ans);
	return 0;
}

【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 貪心+堆