火车进站
题意:
你有一个小站,车站最多能同时接纳三辆火车。先进的火车必须先出。允许同时有多辆火车进出站。
给定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 }