火车进站[Codevs 3595]

来源:互联网 发布:wkwebview 本地js 编辑:程序博客网 时间:2024/04/29 10:15

题目描述 Description

火车站内往往设有一些主干线分叉出去的铁路支路,供火车停靠,以便上下客或装载货物。铁路支路有一定长度;火车也有一定的长度,且每列火车的长度相等。
假设某东西向的铁路上,有一小站。该站只有一条铁路支路可供火车停靠,并且该铁路支路最多能容纳 M 辆火车。为了火车行驶的通畅,该站只允许火车自东方进站,自西方出站,且先进站的火车必须先出站,否则,站内火车将发生堵塞。该火车站工作任务繁忙。每天都有 N 辆自东方驶向西方的火车要求在预定时刻进站,并在站内作一定时间的停靠。
为了满足每辆进站火车的要求,小站的调度工作是井井有条地开展。在小站每天的工作开始前,小站工作人员须阅读所有火车的进站申请,并决定究竞接受哪些火车的申请。而对于不能满足要求的火车,小站必须提前通知它们,请它们改变行车路线,以免影响正常的铁路运输工作。由于火车进站、出站的用时可以忽略不计,小站允许几辆火车同时进站或出站,且小站工作人员可以任意安排这些火车进站的先后排列次序。小站的工作原则是尽量地满足申请火车的要求。
请你编一个程序,帮助工作人员考察某天所有火车的进站申请,计算最多能满足多少火车的要求。


输入描述 Input Description

N1 行。
第一行是两个正整数 NM(N100M3)
以下 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

1n100,1m3


分析 I Think

我们把火车按出站时间从小到大排序
m=1 时,就是一个经典的贪心问题,排序后第一辆车的申请一定被接受,如果不被接受,那么考虑之后第 i 个,因为 tit1,而整个车站只能容纳 1 辆火车,也就是说当且仅当 srtk ( k 表示当前在车站的火车),第 r 辆火车才能进站,所以对于火车 r ,如果 tisrt1 ,在容纳第 1 辆火车允许进入的车辆大于容纳第 i 辆火车时,也就是说如果容纳第 i 辆火车可能会是当前解不会最优,时间复杂度为 O(n)
m=2 时,考虑动态规划,如果 fi,j(i<j,sisj) 表示车站有第 i,j 辆火车时车站可接受的最大申请,显然 f0,i=1,如果 skti,sksj,那么 fj,k=max{fi,j+1},时间复杂度为 O(n3)
m=3 时同 m=2 时,如果 fi,j,k(i<j<k,sisjsk) 表示车站有第 i,j,k 辆火车时车站可接受的最大申请,显然 f0,0,i=1,如果 srti,srsk,那么 fj,k,r=max{fi,j,k+1},时间复杂度为 O(n4)


代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 120;struct time{    int s,t;    bool operator < (const time &h)const {return t<h.t||(t==h.t&&s<h.s);}}a[Size];int f[Size][Size][Size];int n,m;void work1();void work2();void work3();int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;++i)        scanf("%d%d",&a[i].s,&a[i].t);    sort(a+1,a+n+1);    switch(m){        case 1 : work1();break;        case 2 : work2();break;        case 3 : work3();break;    }    return 0;}void work1(){    int early = a[1].t;    int ans = 1;    for(int i=2;i<=n;++i)        if(a[i].s >= early){            ++ans;            early = a[i].t;        }    printf("%d\n",ans);}void work2(){    for(int i=1;i<=n;++i)        f[0][i][0] = 1;    for(int i=1;i<=n;++i)        for(int j=i+1;j<=n;++j)            if(a[j].s >= a[i].s)                for(int k=0;k<i;++k)                    if(a[k].t <= a[j].s)                        f[i][j][0] = max(f[k][i][0]+1,f[i][j][0]);    int ans = 0;    for(int i=0;i<=n;++i)        for(int j=i+1;j<=n;++j)            ans = max(ans,f[i][j][0]);    printf("%d\n",ans);}void work3(){    for(int i=1;i<=n;++i)        f[0][0][i] = 1;    for(int i=0;i<=n;++i)        for(int j=i+1;j<=n;++j)            if(a[j].s >= a[i].s)                for(int k=j+1;k<=n;++k)                    if(a[k].s >= a[j].s)                        for(int r=0;r<(i==0?1:i);++r)                            if(a[r].t <= a[k].s)                                f[i][j][k] = max(f[i][j][k],f[r][i][j]+1);    int ans = 0;    for(int i=0;i<=n;++i)        for(int j=i+1;j<=n;++j)            for(int k=j+1;k<=n;++k)                ans = max(ans,f[i][j][k]);    printf("%d\n",ans);}
0 0
原创粉丝点击