描述
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3466
某城市的地铁是线性的,有n个车站,有M1辆列车从左到右开,M2辆列车从右到左开.在0时刻,你在第一站,要在T时刻到达第n站,其间可以随意换车,要求在车站等待的时间最短.
分析
用dp[i][j]表示在i时刻,在第j站,要达到目的,需要等待多久.显然dp[T][n]=0,对于任意i!=n,dp[T][i]=INF,要求dp[0][1].那么转移方程:
dp[i][j]=1.dp[i+1][j]+1(在车站等一分钟).
2.dp[i+t[j]][j+1](如果有,乘坐向右的列车).
3.dp[i+t[j-1]][j-1](如果有,乘坐向左的列车).
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=50+5,maxt=200+5,INF=0x3fffffff; 5 int n,T,M1,M2,kase; 6 int t[maxn],dp[maxt][maxn]; 7 bool has_train[maxt][maxn][2]; 8 9 void solve(){ 10 for(int i=1;i<=n;i++) dp[T][i]=INF; 11 dp[T][n]=0; 12 for(int i=T-1;i>=0;i--) 13 for(int j=1;j<=n;j++){ 14 dp[i][j]=dp[i+1][j]+1; 15 if(j<n&&has_train[i][j][0]&&i+t[j]<=T) 16 dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]); 17 if(j>1&&has_train[i][j][1]&&i+t[j-1]<=T) 18 dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]); 19 } 20 printf("Case Number %d: ",++kase); 21 if(dp[0][1]>=INF) puts("impossible"); 22 else printf("%d\n",dp[0][1]); 23 } 24 void init(){ 25 scanf("%d",&T); 26 for(int i=1;i<n;i++){ 27 scanf("%d",&t[i]); 28 } 29 memset(has_train,0,sizeof has_train); 30 scanf("%d",&M1); 31 for(int i=1;i<=M1;i++){ 32 int d; scanf("%d",&d); 33 int station=1; 34 while(d<=T&&station<n){ 35 has_train[d][station][0]=true; 36 d+=t[station++]; 37 } 38 } 39 scanf("%d",&M2); 40 for(int i=1;i<=M2;i++){ 41 int d; scanf("%d",&d); 42 int station=n; 43 while(d<=T&&station>0){ 44 has_train[d][station][1]=true; 45 d+=t[station-1]; station--; 46 } 47 } 48 } 49 int main(){ 50 while(scanf("%d",&n)&&n){ 51 init(); 52 solve(); 53 } 54 return 0; 55 }