题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3466
(dp[i][j]) 表示时间 (i) 在站点 (j) 时最少需要等待的时间
每个状态有三种决策,等一分钟,搭向右的火车,搭向左的火车
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 205;
const int INF = 1000000007;
int n, T, M1, M2;
int t[maxn], pt[maxn], st[maxn], d[maxn], e[maxn];
int dp[maxn][maxn], has[maxn][maxn][2];
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
int kase = 0;
while(scanf("%d", &n) == 1 && n){
memset(st, 0, sizeof(st));
memset(pt, 0, sizeof(pt));
memset(has, 0, sizeof(has));
scanf("%d", &T);
for(int i = 1 ; i < n ; ++i){
scanf("%d", &t[i]);
}
for(int i = 2 ; i <= n ; ++i){
pt[i] = pt[i - 1] + t[i - 1];
}
for(int i = n - 1 ; i >= 1 ; --i){
st[i] = st[i + 1] + t[i];
}
// for(int i = 1 ; i <= n ; ++i){
// printf("%d ", pt[i]);
// } printf("
");
// for(int i = 1 ; i <= n ; ++i){
// printf("%d ", st[i]);
// } printf("
");
scanf("%d", &M1);
for(int i = 1 ; i <= M1 ; ++i){
scanf("%d", &d[i]);
for(int j = 1 ; j <= n ; ++j){
has[d[i] + pt[j]][j][1] = 1;
}
}
scanf("%d", &M2);
for(int i = 1 ; i <= M2 ; ++i){
scanf("%d", &e[i]);
for(int j = n ; j >= 1 ; --j){
has[e[i] + st[j]][j][0] = 1;
}
}
// for(int i = 0 ; i <= T ; ++i){
// for(int j = 1 ; j <= n ; ++j){
// printf("%d ", has[i][j][1]);
// } printf("
");
// }
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 && i + t[j] <= T && has[i][j][1]){
dp[i][j] = min(dp[i][j], dp[i + t[j]][j + 1]);
}
if(j > 1 && i + t[j - 1] <= T && has[i][j][0]){
dp[i][j] = min(dp[i][j], dp[i + t[j-1]][j - 1]);
}
}
}
printf("Case Number %d: ", ++kase);
if(dp[0][1] >= INF) printf("impossible
");
else {
printf("%d
", dp[0][1]);
}
}
return 0;
}