列车调度(贪心)

列车调度(贪心)#题目:火车站的列车调度铁轨的结构如下图所示。两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入(一条轨道可以停放多个火车)。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?输入格式…

大家好,又见面了,我是你们的朋友全栈君。

#题目:火车站的列车调度铁轨的结构如下图所示。

列车调度(贪心)

两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入(一条轨道可以停放多个火车)。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?

输入格式:

输入第一行给出一个整数N (2  N ≤10000),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。

输出格式:

在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。

输入样例:

98 4 2 5 3 9 1 6 7

输出样例:

4

#最初做的时候认为一条轨道只能停留一辆火车,还以为答案错了—_—

#此题对于使用贪心的理解:

我们需要尽量减少加轨道条数,也就是新的火车最好能到一条路线的末尾排着,而为了之后的顺序输出,一条轨道上后面的车需要比前面的编号小,这就产生了选择问题。选择时可以归结出以下逻辑:

选择时要减少轨道条数,增加轨道条数的条件是需要进入的火车大于所有链尾序号,所以为了减小这个条件的成立可能性,就需要使每条轨道尽量多地容纳。举个例子,比如我们现在有两条轨道,轨道上的链尾为轨道一:5号,轨道二:8号,我们需要插入4号车,如果将4号插入轨道二,轨道二上4到8之间的插入可能性就被夺取了,同等条件下,将4号插入5号,相当于没有夺取其他任何可插入的可能性。而我们的目的就是增大可以不加轨道条数的可能性(等价于增大链尾能插入的可能性,又等价于增大链尾能插入的数量),所以需要做的是将新的元素插入到与这个元素序号差别最小的链尾。

#使用贪心策略将火车排入轨道后一定能顺序排出,故不需要考虑排出。

#处于效率考虑,需进行一些逻辑的处理。比如,整个过程是没有必要遍历的,我们从第一个轨道开始,其实相当于划分了轨道上序号的范围,由于序号没有重复的,第二个轨道的序号永远会比第一个轨道大。运用这个规律,只要判定最后一条轨道的链尾序号与需插入的相比,就可以确定是否需要建立新轨道。如果不需要建立新轨道,插入的轨道就是从第一条开始遇到的第一个可以插入的轨道。

#代码实现1(二分):

#include<stdio.h>
const int maxn=1e5+5;


int main(){
    int n;
    int a[maxn];
    scanf("%d",&n);
    int k, len=0;
    while(n--){
        scanf("%d",&k);
        if(len==0||a[len-1]<k){
            a[len++]=k;
        }else{
            int l=0, r=len-1;
            while(l<r){
                int mid=l+(r-l)/2;
                if(a[mid]>k)
                    r=mid-1;
                else l=mid+1;
            }
            a[l]=k;
        }
    }
    printf("%d",len);
    return 0;
}

#代码实现2:

#include<stdio.h>
#include<limits.h>
#include<string.h>
int n;
int che[100001];          //che[]用于储存链尾序号
int N;
int count =1;

int foun(int n)
{

    if(n>che[count])
        return 0;
    if(n<che[count]&&n>che[count-1])
        return count;

    for(y=1;y<=count;y++)
       if(n<che[y])    //检查能否插入
             return y;

}
int main()
{
    scanf("%d",&N);
    int i,k,a;
    memset(che,0,sizeof(che));

    che[1]=INT_MAX;
    for(i=1;i<=N;i++)
    {
        scanf("%d",&n);
        if(a=foun(n))
            che[a]=n;   //更新链尾序号
        else                 //不可插入链尾,则创建新轨道
        {
            count++;
            che[count]=n;
        }
    }
     printf("%d",count);

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159411.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • HashMap扩容流程[通俗易懂]

    HashMap扩容流程[通俗易懂]文章目录为什么扩容?什么时候扩容?如何扩容?今天在和同时讨论HashMap的时候,提到了扩容和冲哈希的事情,然后我发现大家都是一种半懂不懂的状态。于是回去做了一番功课,写下这篇文章。HashMap的扩容,又被很多人叫rehash、重哈希,我本人是很反对这个叫法的,事实上HashMap扩容的时候,Node中存储的Key的hash值并没有发生变化,只是Node的位置发生了变化。首先说为什么需要扩…

    2025年11月23日
    3
  • Android 编程之第三方开发 MaoZhuaWeiBo微博开发演示样例-1「建议收藏」

    Android 编程之第三方开发 MaoZhuaWeiBo微博开发演示样例-1

    2022年1月22日
    49
  • 调和数列举例_数列专项训练

    调和数列举例_数列专项训练算法训练调和数列问题时间限制:1.0s内存限制:512.0MB时间限制:1.0s内存限制:512.0MB问题描述输入一个实数x,求最小的n使得,1/2+1/3+1/4+…+1/(n+

    2022年8月5日
    6
  • flash的计算机知识,Flash CS6计算机动画设计教程[通俗易懂]

    flash的计算机知识,Flash CS6计算机动画设计教程[通俗易懂]FlashCS6计算机动画设计教程语音编辑锁定讨论上传视频《FlashCS6计算机动画设计教程》是2014年中国铁道出版社出版的图书,作者是耿增民、刘正东、孙晓东、陈春丽。书名FlashCS6计算机动画设计教程作者耿增民刘正东孙晓东陈春丽ISBN9787113179380页数200出版社中国铁道出版社出版时间2014-03-01装帧平装开本16开版…

    2022年5月8日
    35
  • 常用存储器分类

    常用存储器分类1 存储器是计算机实现记忆功能的部件 用来存放程序和数据 是微机系统中重要的组成部分 存储器的容量越大 表明能存储的信息越多 计算机的处理能力也就越能充分展现 存储器系统由外存储器和内存储器两部分组成 其中内存储器用来存放当前运行的程序和数据 一般由一定容量的速度较高存储器组成 CPU 可直接用指令对内存储器进行读 写操作 内存储器的分类如下 2 RAM RandomAccess

    2025年8月13日
    10
  • 找不到指定的模块

    找不到指定的模块找不到指定的模块。(异常来自HRESULT:0x8007007E)

    2022年7月4日
    21

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号