CodeVS3958 火车进站

3958 火车进站

时间限制: 1 s

空间限制: 256000 KB

题目等级 : 大师 Master

题目描述 Description

火车站内往往设有一些主干线分叉出去的铁路支路,供火车停靠,以便上下客或装载货物。铁路支路有一定长度;火车也有一定的长度,且每列火车的长度相等。

假 设某东西向的铁路上,有一小站。该站只有一条铁路支路可供火车停靠,并且该铁路支路最多能容纳M 辆火车。为了火车行驶的通畅,该站只允许火车自东方进站,自西方出站,且先进站的火车必须先出站,否则,站内火车将发生堵塞。该火车站工作任务繁忙。每天 都有 N  辆自东方驶向西方的火车要求在预定时刻进站,并在站内作一定时间的停靠。

为了满足每辆进站火车的要求,小站的调度工作 是井井有条地开展。在小站每天的工作开始前,小站工作人员须阅读所有火车的进站申请,并决定究竞接受哪些火车的申请。而对于不能满足要求的火车,小站必须 提前通知它们,请它们改变行车路线,以免影响正常的铁路运输工作。由于火车进站、出站的用时可以忽略不计,小站允许几辆火车同时进站或出站,且小站工作人 员可以任意安排这些火车进站的先后排列次序。小站的工作原则是尽量地满足申请火车的要求。

请你编一个程序,帮助工作人员考察某天所有火车的进站申请,计算最多能满足多少火车的要求。

输入描述 Input Description

共N+1 行。

第一行是两个正整数N 和M。(N<=100,M<=3);

以下N 行每行是一辆火车的进站申请,第i+1 行的两个整数分别表示第i 列火车的进站的时间和火车出站的时间。

输出描述 Output Description

仅一行,是一个正整数B,表示火车站最多能接纳的火车数量。

样例输入 Sample Input

6 3

2 4

1 7

3 6

5 7

8 10

9 11

样例输出 Sample Output

5

数据范围及提示 Data Size & Hint

祝各位大牛早日AC

【题解】

分情况讨论。

m = 1时,dp[i]表示i在站台上的最大进站数。dp[i] = max{dp[j] + 1};

要求j在i之前进站且j在i进站前出站

m = 2时,dp[i][j]表示i和j正在站台上的最大进站数。dp[i][j] = max{dp[j][k] + 1};

要求k在j前进站,j在i前进站,且k在i进站前出站

m = 3时,dp[i][j][k]表示i,j,k正在站台上的最大进站数。dp[i][j][k] = max{dp[j][k][l] + 1};

要求k在j前进站,l在k前进站,j在i前进站,且l在i进站前出站

先按进站时间从小到大排序,为了无后效性,从小往大递推。为了判断进站时间相等的若干列车,

i,j,k,l均要从1..n。

50^4数据略大,因此当遇到第一个后面的车进站时间大于前面的车时直接break来减少常数

(实际上常数本来就很小,随便过)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <algorithm>
  7 #define min(a, b) ((a) < (b) ? (a) : (b))
  8 #define max(a, b) ((a) > (b) ? (a) : (b))
  9
 10 inline void read(int &x)
 11 {
 12     x = 0;char ch = getchar(), c = ch;
 13     while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
 14     while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
 15     if(c == ‘-‘)x = -x;
 16 }
 17
 18 const int MAXN = 100 + 10;
 19
 20 int dp1[MAXN], dp2[MAXN][MAXN], dp3[MAXN][MAXN][MAXN], n, m;
 21
 22 struct Node
 23 {
 24     int reach, leave;
 25     Node(int _reach, int _leave){reach = _reach, leave = _leave;}
 26     Node(){}
 27 }node[MAXN];
 28
 29 bool cmp(Node a, Node b)
 30 {
 31     return a.reach == b.reach ? a.leave < b.leave : a.reach < b.reach;
 32 }
 33
 34 int ans;
 35
 36 int main()
 37 {
 38     read(n), read(m);
 39     for(register int i = 1;i <= n;++ i) read(node[i].reach), read(node[i].leave);
 40     std::sort(node + 1, node + 1 + n, cmp);
 41     if(m == 1)
 42     {
 43         ans = min(n, 1);
 44         for(register int i = 1;i <= n;++ i)
 45         {
 46             dp1[i] = 1;
 47             for(register int j = 1;j <= n;++ j)
 48             {
 49                 if(node[j].reach > node[i].reach)break;
 50                 if(i == j || node[j].leave > node[i].reach)continue;
 51                 dp1[i] = max(dp1[i], dp1[j] + 1);
 52             }
 53             ans = max(ans, dp1[i]);
 54         }
 55
 56     }
 57     else if(m == 2)
 58     {
 59         ans = min(2, n);
 60         for(register int i = 1;i <= n;++ i)
 61             for(register int j = 1;j <= n;++ j)
 62             {
 63                 if(node[i].reach < node[j].reach)break;
 64                 if(i == j || node[i].leave < node[j].leave)continue;
 65                 dp2[i][j] = 2;
 66                 for(register int k = 1;k <= n;++ k)
 67                 {
 68                     if(node[k].reach > node[j].reach)break;
 69                     if(j == k || i == k || node[k].leave > node[i].reach || node[k].leave > node[j].leave)continue;
 70                     dp2[i][j] = max(dp2[i][j], dp2[j][k] + 1);
 71                 }
 72                 ans = max(ans, dp2[i][j]);
 73             }
 74     }
 75     else
 76     {
 77         ans = min(n, 3);
 78         for(register int i = 1;i <= n;++ i)
 79             for(register int j = 1;j <= n;++ j)
 80             {
 81                 if(node[j].reach > node[i].reach)break;
 82                 if(i == j || node[i].leave < node[j].leave)continue;
 83                 for(register int k = 1;k <= n;++ k)
 84                 {
 85                     if(node[k].reach > node[j].reach)break;
 86                     if(j == k || i == k || node[j].leave < node[k].leave)continue;
 87                     dp3[i][j][k] = 3;
 88                     for(register int l = 1;l <= n;++ l)
 89                     {
 90                         if(node[l].reach > node[k].reach )break;
 91                         if(l == k || l == i || j == l|| node[l].leave > node[i].reach || node[l].leave > node[k].leave)continue;
 92                         dp3[i][j][k] = max(dp3[i][j][k], dp3[j][k][l] + 1);
 93                     }
 94                     ans = max(ans, dp3[i][j][k]);
 95                 }
 96             }
 97     }
 98     printf("%d", ans);
 99     return 0;
100 }

CodeVS 3958火车进站

时间: 2024-10-28 10:48:27

CodeVS3958 火车进站的相关文章

华为OJ—火车进站(栈,字典排序)

给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号.其实也就是输出所有可能的出栈序列. 样例输入: 3 1 2 3 样例输出: 1 2 31 3 22 1 32 3 13 2 1 解答: 其实核心就是一个栈,对于第K个数,在第K个数进栈之前,前面的 K-1 个数要么全部出去了,要么都在栈里面,要么部分在栈里面部分出去了.那么可以假想,在第K个数入栈之前,依次从栈里面出去 0个.1个.2个--栈.si

(hdu)1022 Train Problem I 火车进站问题

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1022 Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Stati

[华为机试练习题]13.火车进站

题目 描述: 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 题目类别: 栈 难度: 高级 运行时间限制: 10Sec 内存限制: 128MByte 阶段: 入职前练习 输入: 有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample. 样例

全排列——火车进站问题(华为OJ)

今天发现一个非常好用的函数next_permutation(),利用这个函数这以很容易的列出一组数据的所有排列组合. 利用全部排列解决了火车进站问题,下面是题目和源码: 题目:给定一个正整数N代表火车数量,0 #include<vector> #include<stack> #include<string> #include<iostream> #include<algorithm> using namespace std; //////////

C++ HOJ 火车进站

[问题描写叙述] 给定一个正整数N代表火车数量.0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号. 要求以字典序排序输出火车出站的序列号. 输入: 有多组測试用例,每一组第一行输入一个正整数N(0<N<10),第二行包含N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每一个编号以空格隔开,每一个输出序列换行.详细见sample. 例子输入: 3 1 2 3 例子输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 [

栈:火车进站

题目描述 这里有n列火车将要进站再出站-- 但是,每列火车只有1节---那就是车头-- 描述 有n列火车按1到n的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出. (某生:不就是个栈吗?每次可以让右侧头火车进栈,或者让栈顶火车出站? 老师:闭嘴!) 就像这样: 出站<---    <--进站 |车| |站| |__| 现在请你按<字典序>输出前20种可能的出栈方案. 输入 一个

火车进站问题

import java.util.EmptyStackException;import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;import java.util.Stack;public class H06 { /** * @return * @给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列, * 一共N辆火车,每辆火车以数字1-9编号. * 要求以字典序排序输出火车出站的序

栈之火车进站和出站

Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of student want to get back to school by train(because the trains in the Ignatius Train Station is the fastest all over the world ^v^). But here comes

华为机试题 火车进站

描述:给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列 输入: 有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9. 输出: 输出以字典序排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample. 样例输入: 3 1 2 3 样例输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 思路:先对输入序列进行字