题意:某城市的地铁是线性的,有n(2≤n≤50)个车站,从左到右编号为1-n。有M1辆列车从第1站开始往右开,还有M2辆列车从第n站开始往左开。在时刻0,Mario从第1站出发,目的是在时刻T(0≤T≤200)会见车站n的一个间谍。在车站等车时容易被抓,所以她决定尽量躲在开动的火车上,让在车站等待的总时间尽量短。列车靠站停车时间忽略不计,且Mario身手敏捷,即使两辆方向不同的列车在同一时间靠站,Mario也能完成换乘。
输入第1行为n,第2行为T,第3行有n-1个整数t1,t2,…,tn−1(1≤ti≤70),其中ti表示地铁从车站i到i+1的行驶时间(两个方向一样)。第4行为M1(1≤M1≤50),即从第1站出发向右开的列车数目。第5行包含M1个整数d1, d2,…, dM1(0≤di≤250,di<di+1),即各列车的出发时间。第6、7行描述从第n站出发向左开的列车,格式同第4、5行。输出仅包含一行,即最少等待时间。无解输出impossible。
思路:时间是顺序的,影响因素是某一时刻车在哪一个车站,所以建立dp[i][j]表示在第i秒内在第j个车站所等待的时间最少。train[i][j][0]表示在第i秒第j个车站可不可以向右走,可以为真,不可以为假,train[i][j][1]表示从n->1方向移动。在每一个车站有3种可能:1、原地等2、向右乘车(如果可以)3、向左乘车(如果可以)
#include<iostream> #include<vector> #include<algorithm> #include <cstdio> #include<cmath> #include<set> #include<queue> #include<cstring> #include<string> #include<iomanip> #define INF 0x3f3f3f using namespace std; typedef long long ll; const int mod=1e9+7; const int maxn=2100; const double PI=acos(-1.0); const int maxnn = 1e6; int T,m1,m2; int dp[maxn][maxn]; int train[maxn][maxn][2]; int t[maxn]; int main() { int n; int k=0; while(cin >> n && n != 0) { cin >> T; //memset(t,0,sizeof(t)); t[0] = 0; for(int i = 1;i < n;i++) { cin >> t[i]; } cin >> m1; memset(train,0,sizeof(train)); for(int i = 0;i < m1;i++) { int d; cin >> d; int s = d; for(int j = 0;j < n;j++) { s += t[j]; if(s <= T)train[s][j+1][0] = 1; else break; } } cin >> m2; for(int i = 0;i < m2;i++) { int d; cin >> d; train[d][n][1] = 1; int s = d; for(int j = n-1;j > 1 ;j--) { s += t[j]; if(s <= T)train[s][j][1] = 1; else break; } } for(int i = 1;i < n;i++)dp[T][i] = INF; dp[T][n] = 0; for(int i = T-1;i >= 0;i--) { for(int j = 1;j <= n;j++) { dp[i][j] = dp[i+1][j] + 1; if(j < n && train[i][j][0] && i + t[j] <= T)\\向右 dp[i][j] = min(dp[i][j],dp[i+t[j]][j+1]); if(j > 1 && train[i][j][1] && i + t[j-1] <= T)\\向左 dp[i][j] = min(dp[i][j],dp[i+t[j-1]][j-1]); } } if(dp[0][1] >= INF) printf("Case Number %d: impossible\n", ++k); else printf("Case Number %d: %d\n", ++k, dp[0][1]); } return 0; }