zoukankan      html  css  js  c++  java
  • Stall Reservations【贪心】【堆】

    题目大意:

    题目链接:http://poj.org/problem?id=3190
    n条线段,将这些线段塞入一些集合中,要求每个集合的线段互不重合。求最小的集合数和方案。


    思路:

    很明显的贪心。
    最容易想到O(n2)的做法。现将线段以左端点排序,枚举每一条线段和每一个已有集合,如果可以将这条线段放进这个集合中就放。期望分60。
    考虑使用小根堆维护,每次枚举牛就只要和堆顶元素做比较。时间复杂度O(nlogn)


    代码:

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    int n,s[60001],m[60001],tot;
    
    struct node
    {
        int begin,end,num,k;
        //begin表示左端点,end表示右端点,num表示原来是第几条线段,k表示放在了第几个集合
    }c[60001];
    
    bool cmp1(node x,node y)
    {
        return x.begin<y.begin;
    }
    
    bool cmp2(node x,node y)
    {
        return x.num<y.num;
    }
    
    void down(int x)  //下移
    {
        int y=x*2;
        while ((y<=tot&&s[y]<s[x])||(y+1<=tot&&s[y+1]<s[x]))
        {
            if (s[y+1]<s[y]&&y<tot) y++;
            swap(s[x],s[y]);
            swap(m[x],m[y]);
            x=y;
            y=x*2;
        }
    }
    
    void up(int x)  //上移
    {
        int y=x/2;
        while (y>=1&&s[y]>s[x])
        {
            swap(s[x],s[y]);
            swap(m[x],m[y]);
            x=y;
            y=x/2;
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&c[i].begin,&c[i].end);
            c[i].num=i;
        }
        sort(c+1,c+1+n,cmp1);
        s[1]=c[1].end;  //第一个之间放入
        c[1].k=1;
        tot=1;
        m[1]=1;
    
        for (int i=2;i<=n;i++)
         if (s[1]<c[i].begin)  //可以放进去
         {
            s[1]=c[i].end;
            c[i].k=m[1];
            down(1);
         }
         else  //不可以放进去
         {
            s[++tot]=c[i].end;
            c[i].k=tot;
            m[tot]=tot;
            up(tot);
         }
        printf("%d\n",tot);
        sort(c+1,c+1+n,cmp2);
        for (int i=1;i<=n;i++)
         printf("%d\n",c[i].k);
        return 0;
    }
  • 相关阅读:
    友盟统计 新的集成方法
    Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Request"解决方法
    关于如何获取Google 官方 NavgationView中的控件的方法
    使用线程池管理线程!
    文件上传MultipartBody使用方法
    Ddos 分布式拒绝服务 (报告)
    linux+
    模型事件
    广东惠州游
    PhoneGap & Cordova 安装白皮书
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998756.html
Copyright © 2011-2022 走看看