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
- pat
- 【PAT】
- PAT
- PAT
- PAT
- PAT
- PAT
- PAT
- PAT
- PAT
- PAT
- pat
- PAT
- PAT
- PAT
- PAT
- PAT
- PAT
- Spark机器学习之协同过滤
- JavaScript 简单计算器
- XDOJ-1009-Josephus环的复仇(线段树解约瑟夫环)
- Oracle导入带中文的sql文件,报ORA-01756: 引号内的字符串没有正确结束
- C语言中二重指针和指针数组以及数组指针的测试
- PAT
- linux初学 unit10 练习
- 深入理解JVM笔记-第12章
- 面试基础知识整理 —— 树
- c#事件处理小例子
- kaggle 收不到手机验证码
- sql server 游标
- 面试宝典——Java基础
- java 自动获取广播地址