• 题解 P2859 【[USACO06FEB]摊位预订Stall Reservations】


    • 题目链接:

      https://www.luogu.org/problemnew/show/P2859

    • 思路:

      • 首先大家会想到这是典型的贪心,类似区间覆盖问题的思路,我们要将每段时间的左端点从小到大排序,然后一个个插入,插入时比较是否先前的牛棚中已经有牛挤完了奶,如果没有就新增一个牛棚,否则用挤完奶的牛棚。

      • 如果插入时扫描一遍找可用的牛棚的话肯定是会超时的,那么我们就要用一个priority_queue(当然你手写堆也可以)维护先前插入的牛棚中最早挤完奶,即右端点最小的那个。

    • Tips:

      • 注意排序后奶牛的顺序可能是混乱的,而输出是要按原来输入的顺序。我们可以用一个index记录每头奶牛先前的数组下标,以便在记录摊位位置时不会出错。

      • 如何判断每头奶牛在哪个摊位???

        • 虽然感觉第一篇题解的二分+树状数组好神奇但是我看不懂
        • 感觉第三篇的差分好神奇但我还是看不懂

        于是就用了土方法

        我们用一个be数组记录每个奶牛对应的摊位,如果前面没有可插入的奶牛,则新增一个。如果前面有一个奶牛挤完了奶,那么我们就用它的牛棚,具体请看代码实现。

    • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=50005;
    int n,be[maxn],cnt=0;
    struct Cow{
    	int s,e,index;
    }cow[maxn];
    struct Num{    //优先队列记录下标
    	int x;
    	bool operator < (const Num &a) const{
    	return cow[x].e>cow[a.x].e;
    	}
    };
    inline bool cmp1(const Cow &a,const Cow &b){
    	return a.s<b.s;
    }
    priority_queue< Num,vector<Num>>poi;
    int main()
    {
    	cin>>n;
    	for(register int i=1;i<=n;i++){
    		scanf("%d %d",&cow[i].s,&cow[i].e);
    		cow[i].index=i;
    	}
    	sort(cow+1,cow+1+n,cmp1);
    	for(register int i=1;i<=n;i++){
    		Num k;k.x=i;
    		if(!poi.empty()){  
    			Num p=poi.top();//取出队首时间最短的
    			if(cow[p.x].e>=cow[i].s){
    				cnt++;
    				poi.push(k);
    				be[cow[i].index]=cnt;  //注意是index值
    			}
    			else {//如果前面有挤完奶的
    				poi.pop();//注意要pop出来
                    poi.push(k);
                    be[cow[i].index]=be[cow[p.x].index];				//注意这句话,仔细想一想为什么
    			}
    		}
    		else {//如果是第一头牛
    			poi.push(k);
    			cnt++;
    			be[cow[i].index]=cnt;
    		}
    	}
    	cout<<cnt<<endl;
    	for(register int i=1;i<=n;i++){
    		printf("%d
    ",be[i]);
    	}
    	return 0;
    }
    
    • 总结:

      思维难度一般,考验一些小技巧的使用

  • 相关阅读:
    Java_适配器模式
    linux常用命令整理
    (转)使用隐藏的iframe 隐藏form提交,仿AJax无刷新提交,可以实现无刷新上传文件
    mysql添加并返回主键
    学习RMI
    关于bcprov-jdk16
    JavaScript在页面中的引用方法
    通过CFX发布WebService(一)
    字符串和json数据的转换
    MD5 加密与解密
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8643707.html
Copyright © 2020-2023  润新知