贪心—最大区间不相交问题 (加强版)

弱版:https://blog.csdn.net/yanzhenhuai/article/details/81111598


让我们继续来思考这样的一个问题 :

给出n条区间的起点和终点(输入保证所有区间都是起点<终点),每一局可以选出若干个之前没有选出的区间,这些区间满足两两无交集(可以某区间的终点与另一区间的起点相同)。
问最少多少局可以选出所有的区间。


尽管这是最大区间不相交问题的加强版,但是贪心的策略仍然显而易见。

我们在最开始的时候以每个区间的起点为关键字进行从小到大排序。

然后我们考虑维护一个优先队列,这优先队列用来维护每个结束区间的最小值。仍然考虑将排完序后的区间按顺序扫一遍。我们比较开始的时间 T m p 与优先队列当中的最小时间 C u r 的大小。如果 C u r T m p ,那么我们就更新 C u r ,并把更新后的 C u r 放进优先队列当中。

不然的话我们就需要新一局,把结束的时间放进优先队列当中。

参考代码:

#include <queue> 
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
using namespace std;
const int Max=1e5+5;
struct Node{
    int X,Y;
}G[Max];
int T,N,Ans;
inline int Read(){
    int X=0;char CH=getchar();bool F=0;
    while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
    while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
    return F?-X:X;
}
inline void Write(int X){
    if(X<0)X=-X,putchar('-');
    if(X>9)Write(X/10);
    putchar(X%10+48);
}
bool Cmp(Node P,Node Q){
    return P.X<Q.X;
}
int main(){
    int I,J,K;
    T=Read();
    while(T--){
        priority_queue<int,vector<int>,greater<int> >PQ;
        Ans=1;
        N=Read();
        for(I=1;I<=N;I++){
            G[I].X=Read(),G[I].Y=Read();
        }
        sort(G+1,G+1+N,Cmp);PQ.push(G[1].Y);
        for(I=2;I<=N;I++){
            if(PQ.size()!=0){
                int Cur=PQ.top();
                if(G[I].X>=Cur){
                    PQ.pop();Cur=G[I].Y;PQ.push(Cur);
                } else {
                    Ans++;PQ.push(G[I].Y);
                }
            } else {
                Ans++;
                PQ.push(G[I].Y);
            }
        }
        Write(Ans),putchar('\n');
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/81125165