紫皮书 非原创……
某城市的地铁是线性的有n个车站从左到右编号为1-n,有M1辆地铁从第一站出发,有M2辆车从最后一站出发,mario从第一站出发,目的是在时刻T会见车站n的一个朋友(间谍)。在车站等车容易被抓,所以尽量让其在车站的时间尽量短,mario能完成方向不同地铁的换乘
dp[i][j]表示i时刻j站最少还要等多长时间,边界dp[T][n] = 0;其他dp[T][i] 为正无穷
则有三种决策
1.等一分钟
2.搭乘左开的车
3.搭乘右开的车
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <queue> #include <map> #include <set> using namespace std; const int INF = 0xffffff; const double ESP = 10e-8; const double Pi = 4 * atan(1.0); const int MAXN = 200 + 10; const long long mod = 1000000007; const int dr[] = {1,0,-1,0,-1,1,-1,1}; const int dc[] = {0,1,0,-1,1,-1,-1,1}; typedef long long LL; LL gac(LL a,LL b){ return b?gac(b,a%b):a; } int dp[210][MAXN]; int n,T; int t[MAXN]; int M1,M2; int d[MAXN]; int e[MAXN]; bool has_train[210][MAXN][2]; int main(){ #ifndef ONLINE_JUDGE freopen("input.in","r",stdin); // freopen("output.txt","w",stdout); #endif int cas = 1; while(~scanf("%d",&n) && n){ scanf("%d",&T); for(int i = 2;i <= n;i++){ scanf("%d",&t[i]); } t[1] = 0; t[n+1] = 0; memset(has_train,0,sizeof(has_train)); scanf("%d",&M1); for(int i = 1;i <= M1;i++){ scanf("%d",&d[i]); int sum = d[i]; for(int j = 1;j <= n;j++){ sum += t[j]; has_train[sum][j][0] = 1; } } scanf("%d",&M2); for(int i = 1;i <= M2;i++){ scanf("%d",&e[i]); int sum = e[i]; for(int j = n;j > 0;j--){ sum += t[j+1]; has_train[sum][j][1] = 1; } } for(int i = 1;i < n;i++){ dp[T][i] = INF; } dp[T][n] = 0; for(int i = T-1;i > -1;i--){ for(int j = 1;j <= n;j++){ dp[i][j] = dp[i+1][j] + 1;//等待下一个单位 if(j < n && has_train[i][j][0] && i + t[j+1] <= T){ // 从左到右有可以搭乘的车 dp[i][j] = min(dp[i][j],dp[i+ t[j+1]][j+1]); } if(j > 1 && has_train[i][j][1] && i + t[j] <= T){//从右到左有可以搭乘的车 dp[i][j] = min(dp[i][j],dp[i+t[j] ][j-1]); } } } printf("Case Number %d: ",cas++); if(dp[0][1] >= INF){ printf("impossible "); } else{ printf("%d ",dp[0][1]); } } return 0; }