ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目链接:http://poj.org/problem?id=3190
题意:
给定n个闭区间,要让这n个区间拼成m段,(拼的的意思是可以间隔,但不能重叠,如[1,2],[5,6]能拼一起[1,3],[3,4]不能拼一起),要求使得m最小,并输出每个区间属于第几段
题解:
对左端点进行排序,然后依次检查是否能和之前的奶牛和并在一个棚里,具体可以使用两个堆来维护
一个堆从大到小存放左端点,一个堆从小到到存放左端点,然后查询能否合并到左堆或者右堆,否则新开一个棚
为什么对左端点排序?
需要按左边进行排序,不然在合并的过程中会出现这种情况,[1,2],[3,4],[5,6]三个可以合并
但由于顺序为 [1,2],[5,6],[3,4] 使得前两个先合并了,第三个需要新开一个棚
左边相同的情况下右边的大小顺序不重要,因为左边相同的两个必定在两个不同的棚里,合并顺序不影响,因为左合并的话
两者更新产生的新棚的左边是一样的,右合并的话,两者由于必然不在同一个棚子里所以必然产生两个新左端点(当前两头奶牛的左边挤奶时间)
所以,只要两头奶牛不在同一个棚里,合并顺序对后续无影响
所以,我们只要考虑在用一个棚子里的奶牛,按从左到右的顺序合并就好了,所以对左端点排序就好了
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int maxn=50005;
struct node{
int time,id;
node(){}
node(int t, int i):time(t),id(i){}
bool operator < (const node &a)const{
return time<a.time;
}
bool operator > (const node &a)const{
return time>a.time;
}
};
struct Cow{
int l, r, id;
bool operator < (const Cow &a)const{
return l<a.l;
}
}cow[maxn];
int room[maxn],ans[maxn],n;
priority_queue<node, vector<node>, less<node> > L; // 左大根堆
priority_queue<node, vector<node>, greater<node> > R; // 右小根堆
void solve(){
int k = 0;
sort(cow+1,cow+1+n); // 需要按左边进行排序,不然在合并的过程中会出现这种情况,[1,2],[3,4],[5,6]三个可以合并
fo(i,1,n){ // 但由于顺序为 [1,2],[5,6],[3,4] 使得前两个先合并了,第三个需要新开一个棚
bool flag = false; // 左边相同的情况下右边的大小顺序不重要,因为左边相同的两个必定在两个不同的棚里,合并顺序不影响,因为左合并的话
// 两者更新产生的新棚的左边是一样的,右合并的话,两者由于必然不在同一个棚子里所以必然产生两个新左端点对后续无影响
if(!L.empty()){ // 合并在左
int t = L.top().time,id=L.top().id;
if(t>cow[i].r){
L.pop(); // 更新棚
L.push(node(cow[i].l,id));
ans[cow[i].id] = id;
flag = 1;
}
}
if(!flag&&!R.empty()){// 合并在右
int t = R.top().time,id=R.top().id;
if(t<cow[i].l){// 更新棚
R.pop();
R.push(node(cow[i].r,id));
ans[cow[i].id] = id;
flag = 1;
}
}
if(!flag){ // 不能合并,新建一个棚
ans[cow[i].id]=++k;
L.push(node(cow[i].l,k));
R.push(node(cow[i].r,k));
}
}
printf("%d\n",k);
fo(i,1,n)printf("%d\n",ans[i]);
}
int main(){
scanf("%d",&n);
fo(i,1,n)scanf("%d%d",&cow[i].l,&cow[i].r),cow[i].id=i;
solve();
return 0;
}