火车进站

题意:

你有一个小站,车站最多能同时接纳三辆火车。先进的火车必须先出。允许同时有多辆火车进出站。

给定n<=100个火车的进出站时刻,不必一一接纳,求最多能接纳多少火车。

解:

由于是个DP,我一开始想的是把时间离散化之后按照时间来。

f[i][j][k][l]表示前i辆火车,三条轨道的最后时刻分别是jkl时的最大接纳量。

然后发现数组开不下...然后发现哪来三个轨道啊,只有一个......

然后发现网上居然有题解。

设f[i][j][k]表示车站内的顺序是k->j->i,i最先来。

然后枚举由j->i->p的情况转移过来。

记得判断当前状态是否合法。

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 const int N = 110;
 5 
 6 int f[N][N][N];
 7 std::pair<int, int> a[N];
 8 
 9 int main() {
10     int n, m;
11     scanf("%d%d", &n, &m);
12     for(int i = 1; i <= n; i++) {
13         scanf("%d%d", &a[i].first, &a[i].second);
14     }
15     std::sort(a + 1, a + n + 1);
16     int ans = 1;
17     if(m == 1) {
18         for(int i = 1; i <= n; i++) {
19             f[i][0][0] = 1;
20             for(int j = 1; j < i; j++) {
21                 if(a[j].second <= a[i].first) {
22                     f[i][0][0] = std::max(f[i][0][0], f[j][0][0] + 1);
23                 }
24             }
25             ans = std::max(ans, f[i][0][0]);
26         }
27         printf("%d", ans);
28         return 0;
29     }
30     if(m == 2) {
31         for(int i = 1; i <= n; i++) {
32             for(int j = i + 1; j <= n; j++) {
33                 if(a[i].second > a[j].second) {
34                     continue;
35                 }
36                 f[i][j][0] = 2;
37                 for(int k = 1; k < i; k++) { /// j - i - k
38                     if(a[k].second <= a[j].first) {
39                         f[i][j][0] = std::max(f[i][j][0], f[k][i][0] + 1);
40                     }
41                 }
42                 ans = std::max(ans, f[i][j][0]);
43             }
44         }
45         printf("%d", ans);
46         return 0;
47     }
48     for(int i = 1; i <= n; i++) {
49         for(int j = i + 1; j <= n; j++) {
50             if(a[i].second > a[j].second) {
51                 continue;
52             }
53             for(int k = j + 1; k <= n; k++) {
54                 if(a[j].second > a[k].second) {
55                     continue;
56                 }
57                 f[i][j][k] = 3;
58                 for(int p = 1; p < i; p++) { // k - j - i - p
59                     if(a[p].second <= a[k].first) {
60                         f[i][j][k] = std::max(f[i][j][k], f[p][i][j] + 1);
61                     }
62                 }
63                 ans = std::max(ans, f[i][j][k]);
64             }
65         }
66     }
67     printf("%d", ans);
68     return 0;
69 }
AC代码

 

posted @ 2018-09-28 10:13  garage  阅读(247)  评论(0编辑  收藏  举报