题意:
有线性的n个车站,从左到右编号分别为1~n。有M1辆车从第一站开始向右开,有M2辆车从第二站开始向左开。在0时刻主人公从第1站出发,要在T时刻回见车站n 的一个间谍(忽略主人公的换乘时间)。输出最少的等待时间,如果无解输出impossible。
分析:
d(i, j)表示第i时刻在第j个车站,最少还需要的等待时间。边界是:d(T, n) = 0, d(T, i) = +∞
预处理:
has_train[t][i][0]数组是用来记录t时刻第i个车站是否有向右开的车,类似has_train[t][i][1]记录的是向左开的车。
有3种决策:
- 等一分钟
- 搭乘向左开的车(如果有的话)
- 搭乘向右开的车(如果有的话)
边界没有处理到位,WA了好多次。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int INF = 1000000000; 8 int has_train[255][55][2], t[55], dp[255][55]; 9 10 int main(void) 11 { 12 #ifdef LOCAL 13 freopen("1025in.txt", "r", stdin); 14 #endif 15 16 int kase = 0, n, T; 17 while(scanf("%d", &n) == 1 && n) 18 { 19 scanf("%d", &T); 20 for(int i = 1; i < n; ++i) dp[T][i] = INF; 21 dp[T][n] = 0; 22 memset(has_train, 0, sizeof(has_train)); 23 24 for(int i = 1; i < n; ++i) scanf("%d", &t[i]); 25 int m, ti; 26 scanf("%d", &m); 27 while(m--) 28 { 29 scanf("%d", &ti); 30 for(int i = 1; i < n; ++i) 31 { 32 if(ti <= T) has_train[ti][i][0] = 1; 33 ti += t[i]; 34 } 35 } 36 scanf("%d", &m); 37 while(m--) 38 { 39 scanf("%d", &ti); 40 for(int j = n-1; j >= 1; --j) 41 { 42 if(ti <= T) has_train[ti][j + 1][1] = 1; 43 ti += t[j]; 44 } 45 } 46 47 for(int i = T - 1; i >= 0; --i) 48 { 49 for(int j = 1; j <= n; ++j) 50 { 51 dp[i][j] = dp[i+1][j] + 1; 52 if(j < n && has_train[i][j][0] && i + t[j] <= T) 53 dp[i][j] = min(dp[i][j], dp[i + t[j]][j+1]); 54 if(j > 1 && has_train[i][j][1] && i + t[j-1] <= T) 55 dp[i][j] = min(dp[i][j], dp[i + t[j-1]][j-1]); 56 } 57 } 58 59 printf("Case Number %d: ", ++kase); 60 if(dp[0][1] >= INF) puts("impossible"); 61 else printf("%d\n", dp[0][1]); 62 } 63 64 return 0; 65 }
代码君
时间: 2024-10-25 05:30:59