zoukankan      html  css  js  c++  java
  • POJ 3190 Stall Reservations

    问题抽象成数学概念就是:给你n条线段,问最少需要分成几组,使得每组中的线段互不相交

    贪心:

    把线段按左端点排序,对于每一组,我们用一个变量t记录这组里面的线段中的最大的右端点

    对于每一条线段,我们找到t最大且<左端点的那组,把这条线段加进该组,同时更新该组的t

    这里可以用set中的lower_bound()实现

     //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define pb(a) push_back(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    void debug()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("d:\in.txt","r",stdin);
       // freopen("d:\out1.txt","w",stdout);
    #endif
    }
    char getch()
    {
        char ch;
        while((ch=getchar())!=EOF)
        {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    
    struct cow  //
    {
        int l,r,id;
        bool operator <(cow a)const
        {
            if(l!=a.l)
                return l<a.l;
            else return r<a.r;
        }
    }x[50010];
    struct stall  //stall
    {
        int t,id;
        bool operator <(stall a)const
        {
    
            return t<a.t;
        }
    };
    int ans[50010];
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&x[i].l,&x[i].r);
                x[i].id=i;
            }
            multiset<stall> s; 
            sort(x+1,x+1+n);
            int num=0;// 记录组数
            for(int i=1;i<=n;i++)
            {
                int val=x[i].l;
                multiset<stall>::iterator it;
                it=s.lower_bound((stall){val,1}); 
                //lower_bound找到的是大于等于val的第一个数,最大且小于val的就是前面一个
    
                if(it==s.begin())
                {
                    //如果找不到,新开一组
                    s.insert((stall){x[i].r,++num});
                    ans[x[i].id]=num;
                }else
                {
                    //存在,加进去
                    it--;
                    stall k=*it;
                    k.t=x[i].r;
                    ans[x[i].id]=k.id;
                    s.erase(it);
                    s.insert(k);
                }
            }
            printf("%d
    ",num);
            for(int i=1;i<=n;i++)
                printf("%d
    ",ans[i]);
            return 0;
        }
        return 0;
    }
    View Code

     隔了几个月再遇到这道题,发现没必要找t最大的那组,只要小于左端点就行了。

    用优先队列可以比较方便

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    #define pb(a) push(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("in.txt","r",stdin);
        //freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    struct cow
    {
        int first,second,id;
        bool operator < (const cow &ant) const
        {
            if(first!=ant.first) return first<ant.first;
            else return second<ant.second;
        }
    };
    const int maxn = 50005;
    cow da[maxn];
    
    struct Node
    {
        int x,id;
        bool operator < (const Node &ant) const
        {
            return x>ant.x;
        }
    };
    
    
    int res[maxn];
    int main()
    {
        int n;
        std::ios::sync_with_stdio(false);
        while(cin>>n)
        {
            for(int i=0;i<n;i++)
            {
                cin>>da[i].first>>da[i].second;
                da[i].id=i;
            }
            sort(da,da+n);
            priority_queue<Node> q;
            int scnt=0;
    
            for(int i=0;i<n;i++)
            {
                int l=da[i].first,r=da[i].second;
                if(!q.empty()&&q.top().x<l)
                {
                    Node k=q.top();q.pop();
                    k.x=r;
                    q.push(k);
                    res[da[i].id]=k.id;
                }else
                {
                    q.push((Node){r,++scnt});
                    res[da[i].id]=scnt;
                }
            }
            cout<<scnt<<endl;
            for(int i=0;i<n;i++)
                cout<<res[i]<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    manjaro 安装mysql
    Ubuntu安装Redis
    Ubuntu安装docker
    VirtualBox 安装 Ubuntu虚拟机 显卡驱动
    ubuntu 卸载软件
    Linux下环境变量设置的三种方法:
    error: open of glibc-devel-2.12-1.132.el6.i686.rpm failed: 没有那个文件或目录
    ip地址0.0.0.0与127.0.0.1的区别(转载)
    cmake的安装和卸载
    qmake 提示 Failure to open file:****
  • 原文地址:https://www.cnblogs.com/BMan/p/3238519.html
Copyright © 2011-2022 走看看