PAT

来源:互联网 发布:sql server 字符串主键 编辑:程序博客网 时间:2024/06/07 17:07

Problem : 列车调度
Desciption :

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

Solution :

求下界的二分搜索。看图,我们只需要保证每条铁轨上的火车序号是增序,那么就能保证出口的那条铁轨上的火车是增虚,一步一步来,第一条铁轨肯定是{8, 4, 2}, 遇到了[5], 则新开一条铁轨{5}, 之后的[3]进入第二条铁轨{5, 3},依此类推,最终的铁轨列车分布情况是:{8, 4, 2, 1}, {5, 3}, {9, 6}, {7}.我们记下每条铁轨的最后一个序号,也就是{1, 3, 6, 7}。这是个递增序列,而且根据常识,我们要把列车序号尽可能地挨在一起,这样可以避免新开铁轨,也就是说我们的列车在铁轨上要紧凑!接下来的工作就是一个求下界的二分查找来找到比当前数字大且最小的那个位置就可以了,如果找不到,就新开一条铁轨。

这是不是和最长上升子序列的O(nlogn)的求法很像!没错,这道题其实就是在求最长上升子序列。根据Dilworth定理,链的最少划分数 = 反链的最长长度,也就是说最少的最长下降序列个数就等于整个序列最长上升子序列的长度。

Code(C++) :

#include <stdio.h>#define MAX_LINE 100005int n, a[MAX_LINE];int dp[MAX_LINE];int main(){    while (~scanf("%d", &n)) {        for (int i = 0; i < n; i++)            scanf("%d", &a[i]);        int ans = 1;        dp[0] = a[0];        for (int i = 1; i < n; i++) {            int l = 0, r = ans, mid = 0;            while (l < r) {                mid = (l + r) / 2;                if (dp[mid] < a[i])                    l = mid + 1;                else                    r = mid;            }            if (r == ans)                dp[ans++] = a[i];            else                dp[r] = a[i];        }        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 c1驾证过期没审怎么办 驾照报名三年过期了怎么办 新车行驶证过期了怎么办 行驶证忘了审怎么办 摩托车驾驶证副本丢了怎么办 人被全险车撞了怎么办 被全险车撞了怎么办 驾驶证和行驶证遗失怎么办 户口迁移身份证没换驾照怎么办 户口迁回时身份证掉了怎么办 户口毕业托管身份证掉了怎么办 身份证和户口都掉了怎么办 毕业生户口迁回原籍没身份证怎么办 落户上海后怎么办医保卡 小车临时牌过期了怎么办 驾驶证地址错了一个字怎么办 驾驶证名下车辆有违章怎么办 a2如果扣12分怎么办 b2一次超速12分怎么办 b2本扣了12分怎么办 驾照扣了27分怎么办 大车一次扣12分怎么办 a2驾照扣10分怎么办 驾驶证强制降级没给驾驶证怎么办 6P升11.2卡了怎么办 b2驾照记满12分怎么办 c1驾驶证没分了怎么办 驾照扣了15分怎么办 驾驶证暂扣六个月后怎么办 醉驾交警不通知怎么办 参军后地方驾驶证年审怎么办 军人驾驶证到期身份证注销了怎么办 资格证脱审30天怎么办 驾驶证c证扣6分怎么办 驾照被扣了9分怎么办 驾驶证被扣了9分怎么办 a2驾驶本扣3分怎么办 c1e没过扣了满分怎么办 c1一下扣12分怎么办 换证体检过不了怎么办 唐山驾驶本到期换本怎么办