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;
    }
  • 相关阅读:
    扫描线算法
    评论备份(3)
    评论备份(2)
    二分法的注意事项
    sam模板
    Machine Learning(Andrew Ng)学习笔记
    洛谷P2221 [HAOI2012]高速公路
    洛谷P3233 [HNOI2014]世界树
    P2515 [HAOI2010]软件安装
    BZOJ4293: [PA2015]Siano
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998755.html
Copyright © 2011-2022 走看看