列车调度(set)--一些思路讲解

列车调度(set)--一些思路讲解_第1张图片

#include 
using namespace std;
set<int>s;
int main()
{
    int num,n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>num;
        if(s.upper_bound(num)!=s.end())
            s.erase(s.upper_bound(num));
        s.insert(num);
    }
    cout<<s.size();
    return 0;
}
  • 我的思路是既然火车最后要按次序输出,那么我们先模拟一个极端情况。
    刚开始即有一堆有序的火车。
    1 2 3 4 5 6 7 8 9
    那么只需占用一条轨道即可。
    稍微打乱一点后。
    2 1 3 4 5 6 7 8 9
    前7个数字过去没问题,到1的时候就要等一等,因为后面有比1大的数字2,而2应排在1的前面。
    2此时便要独占一条新的轨道,而让它能走在1的前面。最终需要2条轨道。
    再打乱一点后。
    3 2 1 4 5 6 7 8 9
    到1的时候我们知道要给2新开一条轨道,那3呢?显然,2还要再等一等3。所以又要给3新开一条轨道,此时在等3的数字有1和2,我们发现1和2此时都是各自轨道的末尾,新进入的3也占据一个轨道末尾。即所有需要特殊对待的数字都在轨道的末端,因为前面的数字的问题已被解决。

  • 推广一下思路。结合set的知识,我们只用处理轨道末的数字,开一个set记录这几个数字。为什么要用set呢,我们发现在这道题里我们需要对轨道末的数字排序。参考之前的例子,我们再设计一个以弄清规律。
    3 4 2 1 5 6 7 8 9
    巴拉巴拉前几个数字过去后,又到2了。2后面有两个比它大的数,但是我们模拟一下就知道,给4新开一条轨道后不需要再给3开轨道了,因为3可以再4的后面取代4的轨道未地位,1、2作为轨道未要一直等到3、4过去后才能动。我们发现当处理的那个数字能在轨道末找到恰好大于它
    的数字时,它就可以排在其后不用新开轨道。至于为什么要恰好大于,大家可以自己举例模拟一下,这里不再赘述。
    最后代码如上图。每次新数进来,用upper_bound()这个很方便的函数在set里找有没有恰好大的数字。没有即查找到s.end(),若找到了,便可删除找到的数,让新数取而代之其末尾的位置。最终set里还剩几个末尾,便代表有几个轨道。即set的尺寸。

参考 https://blog.csdn.net/mo_yy/article/details/78231022?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

你可能感兴趣的:(列车调度(set)--一些思路讲解)