• 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火车进站
  • 相关阅读:
    RabbitMQ学习笔记
    Eclipse下JRebel的安装和基本使用
    通过HTTP响应头让浏览器自动刷新
    CentOS6.5安装Jenkins
    Windows快捷操作技巧
    关于代码压缩混淆加密整理;
    一款优雅的小程序拖拽排序组件实现
    记一次 Mac CA证书 问题
    微信小程序-Swiper和下拉刷新组件
    WeUI Picker组件 源代码分析
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7492800.html
Copyright © 2020-2023  润新知