题意:
见紫书
时间是一直向前的, 那么我们以时间为序进行 d p dp dp
状态 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示在第 i i i分钟的时候,在第 j j j个车站最小需要等待多长时间
状态的转移有且只有可能从上一次的车站转移过来的 决策时起点为 d p [ T ] [ n ] = 0 dp[T][n]=0 dp[T][n]=0即在第T时间到达地 n n n个站点需要多上时间, 逆序的求解就可以了
状态转移方程为 d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , d p [ i + 1 ] [ j ] + 1 ) dp[i][j]=min(dp[i][j],dp[i+1][j]+1) dp[i][j]=min(dp[i][j],dp[i+1][j]+1)
// Created by Yishui
// Time on 2018/10/
// E-mail: Yishui_wyb@outlook
/*---------------------------------*/
#include <bits/stdc++.h>
using namespace std;
#define cpp_io() {ios::sync_with_stdio(false); cin.tie(NULL);}
#define rep(i,a,n) for (int i=a;i<n;i++)
#define repp(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define CLR(a,b) memset(a,(b),sizeof(a))
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ls o<<1
#define rs o<<1|1
typedef long long ll;
typedef vector<int> VI;
const int MAXN = (int)1e3+10;
const int INF = 0x3f3f3f3f;
const int mod = (int)1e9+7;
void F() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
}
int t[MAXN];
int vis1[MAXN][MAXN],vis2[MAXN][MAXN];
int dp[MAXN][MAXN];
//dp[i][j] 表示i时刻在j车站需要等待的最短时间
int main() {
cpp_io();
int n,k=0;
while(cin>>n) {
if(n==0) break;
CLR(vis1,false); CLR(vis2,false); CLR(dp, 0);
int T; cin>>T;
rep(i,1,n) cin>>t[i];
int m1,m2,xx; cin>>m1;
repp(i,1,m1) {
cin>>xx;
int x=xx;
repp(j,1,n) {
vis1[j][x]=true; x+=t[j];
}
}
cin>>m2;
repp(i,1,m2) {
cin>>xx; int x=xx;
for(int j=n;j>=1;--j) {
vis2[j][x]=true; x+=t[j-1];
}
}
// cout<<dp[T][0]<<"-----\n";
rep(i,1,n) 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 && vis1[j][i] && i+t[j]<=T)
dp[i][j]=min(dp[i][j], dp[i+t[j]][j+1]);
if(j>1 && vis2[j][i] && i+t[j-1]<=T)
dp[i][j]=min(dp[i][j], dp[i+t[j-1]][j-1]);
}
}
cout<< "Case Number " <<++k<< ": ";
if(dp[0][1]>=INF) cout<<"impossible\n";
else cout<<dp[0][1]<<"\n";
}
return 0;
}