一、题目
某城市的地铁是线性的,有n(2 ≤ n ≤ 50)个车站,从左到右编号为1~n。有M1辆车从第一站开始往右开,还有M2辆从第n站开始往左开。在时刻0,Mario从第一站出发,目的是在T时刻会见在n站的一个间谍。要求其在车站的等待时间足够短。
二、解题思路
状态由当前时间和当前所在站决定,我们可以用dp[i][j]表示在时刻t,第i站最少还需要等待的时间。易只T时刻的情况容易确定,
dp[T][j] = (j == n ? INF : 0),而T时刻之前的dp值,可以由T时刻及其之后的决定。
即dp[i][j] = max(dp[i][j] + 1,dp[i + t[j]][j + 1],dp[i + t[j - 1][j - 1]]) (加入三种选择都存在时)
根据状态转移方程和边界值,我们就可以从下至上填满整个表格,dp[0][1]就是要求的。
三、代码实现
1 #include2 #include 3 #include<string.h> 4 #include 5 #include 6 using namespace std; 7 8 const int INF = 0x3f3f3f3f; 9 const int maxn = 50 + 10; 10 const int maxt = 200 + 10; 11 int n, T, cost_time[maxn],M1,M2; 12 int dp[maxt][maxn]; //dp[t][i]表示在时刻t,第i站最少还需要等待的时间 13 int has_train[maxt][maxn][2]; //has_train[i][j][0]表示i时刻,在j车站有开往左的火车,has_train[i][j][1]表示i时刻,在j车站有开往右的火车 14 int kase = 1; 15 16 void slove() 17 { 18 memset(dp, 0, sizeof(dp)); 19 20 for (int i = 1; i <= n - 1; i++) dp[T][i] = INF; //时刻T,在非n的站,是不可能的,把等待时间设置为无穷大 21 dp[T][n] = 0; //时刻T,在第n站,等待时间为0 22 23 for (int i = T- 1; i >= 0; i--) 24 { 25 for (int j = 1; j <= n; j++) 26 { 27 dp[i][j] = dp[i + 1][j] + 1; 28 if (j < n && has_train[i][j][1] && i + cost_time[j] <= T) 29 dp[i][j] = min(dp[i][j], dp[i + cost_time[j]][j + 1]); 30 if (j > 1 && has_train[i][j][0] && i + cost_time[j - 1] <= T) 31 dp[i][j] = min(dp[i][j], dp[i + cost_time[j - 1]][j - 1]); 32 } 33 } 34 printf("Case Number %d: ", kase++); 35 if (dp[0][1] >= INF) printf("impossible\n"); 36 else printf("%d\n", dp[0][1]); 37 } 38 39 int main() 40 { 41 while (scanf("%d",&n) == 1 && n) 42 { 43 memset(has_train, 0, sizeof(has_train)); //这里必须清零 44 scanf("%d", &T); 45 for (int i = 1; i < n; i++) 46 scanf("%d", &cost_time[i]); 47 48 scanf("%d", &M1); 49 int start; 50 for (int i = 0; i < M1; i++) 51 { 52 scanf("%d", &start); 53 int tmp = 0; 54 for (int j = 1; j <= n && start + tmp <= T; j++) //只需考虑T之内的 55 { 56 has_train[start + tmp][j][1] = true; 57 if(j != n) tmp += cost_time[j]; //cost_time不能取到n 58 } 59 } 60 61 scanf("%d", &M2); 62 for (int i = 0; i < M2; i++) 63 { 64 scanf("%d", &start); 65 int tmp = 0; 66 for (int j = n; j >= 1 && start + tmp <= T; j--) 67 { 68 has_train[start + tmp][j][0] = true; 69 tmp += cost_time[j - 1]; 70 } 71 } 72 73 slove(); 74 } 75 return 0; 76 }
四、经验
ctime变量与标准库里自带的冲突了;之前数组开小了,导致Runtime error。