一直re,开大数组才过
#include <cstdio>
#include <cstring>
const int INF= 0x7fffffff;
const int maxn=440;
int min(int a,int b){return a<b?a:b;}
int N,T,M1,M2;
int t[maxn];
bool has_train[maxn][maxn][2];
int main() {
int _case=0;
while (scanf("%d",&N)!=EOF&&N!=0) {
memset(has_train,false ,sizeof(has_train));
scanf("%d",&T);
for (int i=1; i<=N-1; i++) scanf("%d",&t[i]);
scanf("%d",&M1);
for (int i=1; i<=M1; i++){
int sumt;
scanf("%d",&sumt);
//计算has_train
has_train[sumt][1][0]=true;
for (int j=1; j<N-1; j++) {
sumt+=t[j];
has_train[sumt][j+1][0]=true;
}
}
scanf("%d",&M2);
for (int i=1; i<=M2; i++){
int sumt;
scanf("%d",&sumt);
//计算has_train
has_train[sumt][N][1]=true;
for (int j=N-1; j>1; j--) {
sumt+=t[j];
has_train[sumt][j][1]=true;
}
}
int dp[maxn][maxn];
dp[T][N]=0;
for (int i=1; i<N; i++) dp[T][i]=INF;
for (int i=T-1; i>=0;i--)
for (int j=1; j<=N; j++) {
//1.等一分钟
dp[i][j]=dp[i+1][j]==INF?INF:dp[i+1][j]+1;//由下一分钟还在这个j站台转移来
//2.搭乘左往右
if (j<N&&has_train[i][j][0]&&t[j]+i<=T)
dp[i][j]=min(dp[i][j], dp[t[j]+i][j+1]);//由t[j]+i时刻在j+1站台转移来
//3.搭乘右往左
if (j>1&&has_train[i][j][1]&&t[j-1]+i<=T)
dp[i][j]=min(dp[i][j], dp[t[j-1]+i][j-1]);//由t[j-1]+i时刻在j-1站台转移来
}
if (dp[0][1]!=INF) printf("Case Number %d: %d\n",++_case,dp[0][1]);
else printf("Case Number %d: impossible\n",++_case);
}
return 0;
}