本题思路为以时间为“序”,用dp[i][j]表示时刻i,在车站j还需要等待多少时间
边界条件为dp[T][n]=0.
在1个车站 可以有3种决策:
1:等1分钟
2:搭向左去的车。
3:搭向右去的车。
代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n,T,M1,M2,t[99],m1[99],m2[99];
int has_train[999][99][2]; //表示在时刻i车站j是否有车开往右/或者左
int dp[999][99];
int case1=1;
int main(){
while(scanf("%d%d",&n,&T)!=EOF){
if(n==0) break;
memset(t,0,sizeof(t));
memset(m1,0,sizeof(m1));
memset(m2,0,sizeof(m2));
memset(has_train,0,sizeof(has_train));
memset(dp,0,sizeof(dp));
for(int i=1;i<n;i++)
scanf("%d",&t[i]);
scanf("%d",&M1);
for(int i=1;i<=M1;i++){ //输入数据并且建立has_train[][][].
scanf("%d",&m1[i]);
int sum=m1[i];
for(int n1=1;n1<=n;n1++){
sum+=t[n1-1];
has_train[sum][n1][0]++;
}
}
scanf("%d",&M2); //输入数据并且建立has_train[][][].
for(int i=1;i<=M2;i++){
scanf("%d",&m2[i]);
int sum=m2[i];
for(int n2=n;n2>=1;n2--){
sum+=t[n2];
has_train[sum][n2][1]++;
}
}
for(int i=1;i<=n-1;i++)
dp[T][i]=(1<<30); //与0区分开来,用于下面判断是否进行过计算
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; //等待1分钟。
if(j<n&&has_train[i][j][0]&&i+t[j]<=T)
dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
if(j>1&&has_train[i][j][1]&&i+t[j-1]<=T)
dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]);
}
printf("Case Number %d: ",case1++);
if(dp[0][1]<(1<<30))
printf("%d\n",dp[0][1]);
else
printf("impossible\n");
}
return 0;
}