1. 程式人生 > >【51NOD—貪心演算法專題】 E 做任務三 區間貪心+不相交子區間最少人數

【51NOD—貪心演算法專題】 E 做任務三 區間貪心+不相交子區間最少人數

做任務三 

基準時間限制:1 秒 空間限制:131072 KB 分值: 5
B君和m個人一起,要完成n個任務,在這個題中,B君和m個人,什麼都不做。
第i個任務有一個開始時間s[i]和結束時間e[i](保證s[i]<=e[i]),一個人完成兩個任務的時間區間,
不能有交集,但是可以首尾相連。(參考樣例)
換句話說,如果一個人依次完成了(s[1], e[1]) (s[2], e[2]) (s[3], e[3])這3個任務,
那麼這3個任務需要滿足s[1]<=e[1]<=s[2]<=e[2]<=s[3]<=e[3]。
同一個任務只能完成一次,並且中間不能換人。
B君和m個人,想知道要想完成這些任務,至少需要幾個人?
(單組 n <= 100000)
(所有 n 求和 <= 200000)
(開始時間和結束時間,都是非負整數,且在int範圍內。)
(開始時間 <= 結束時間,如果等於的話,意味著這個任務可以瞬間被做完,但是不能沒有人做)

Input

多組資料,第一行是資料組數。
每組資料的第一行兩個整數n, m分別表示任務數,和人數。
以下n行,每行兩個整數表示任務的開始時間和結束時間。

Output

對於每組資料輸出一個整數
表示完成這些任務至少需要多少人。

Input示例

4
2 1
1 3
2 4
2 1
1 3
3 5
2 1
1 3
2 2
4 1
1 2
2 2
2 2
2 3

Output示例

2
1
2
1

思路1

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int nmax=200000+10; 
pair<int,int>a[nmax];
 
int main(int argc, char** argv) {
    int t;
	while(cin>>t){
		while(t--){
			priority_queue<int>q;
			int n;//任務數 
			int m;//人數
			cin>>n>>m;
			for(int i=0;i<n;i++){
				cin>>a[i].first>>a[i].second;
			} 
            sort(a,a+n);//按照first排序
            //加入相反數實現小根堆的效果,就是根是絕對值越小的 
            int z=0;
			for(int i=0;i<n;i++){
				//遇到一個新任務,試圖讓q.top()去接
				//如果能接,則更新 
				if(q.size()>0&&-q.top()<=a[i].first){
					q.pop();//彈出q.top();
					q.push(-a[i].second);
				}
				//如果不能接,則新開一個人去接
				else{
					q.push(-a[i].second);
					z++; 
				} 
			} 
			cout<<z<<endl;
		}
	} 
	return 0;
}

————————————————————————————————————————————————————————

思路2

#include <iostream>
#include <set>
#include <cstdio>
#include <algorithm>
using namespace std;
const int nmax=200000+20;
pair<int,int>a[nmax];
 
int main(int argc, char** argv) {
	int t;
	while(cin>>t){
		while(t--){
			int n;
			int m;
			cin>>n>>m;
			for(int i=0;i<n;i++){
				cin>>a[i].second>>a[i].first;
			}
			sort(a,a+n);//按照first排序 
			multiset<int>s;//維護所有人的結束時間
			int z=0;
			//如果能接(小於等於開始時間)的最晚的人 
			//upper_bound找到大於等於最早的 
			//--upper_bound 就是小於等於最晚的 
			for(int i=0;i<n;i++){
				if(s.size()>0&& *s.begin()<=a[i].second){
					s.erase(--s.upper_bound(a[i].second));
					//--s.upper_bound(a[i].second); 
					s.insert(a[i].first); 
				} 
				//如果接不了此任務,新開一個人 
				else{
					s.insert(a[i].first);
					z++;
				}
			}
			//cout<<z<<endl; 
			printf("%d\n",z);
		}
	}
	return 0;
}