题目大意:
在一个有n个站台的地铁线路里,给你列车通向每相邻两个车站所花费的时间,从0时刻开始,从1号站出发,要在T这个时间点上,到达n号站,给你m1辆从1开到n的列车及其出发时间,和m2辆从n开到1的列车及其出发时间,求在车站停留的最短时间(注意,如果你在T之前的T’时到达n号站,那你也要花费T-T’的时间停留),如果无论如何也到不了n号站,输出“Impossible”
设f[i][j]表示在第i时刻到达j号车站,将每辆列车到每个站的时间预处理一下,则状态转移方程为:
f[i][j]=min(f[i][j],min(f[train1[o][j-1]][j-1]+i-train1[o][j],f[train2[o][j+1]][j+1]+i-train2[o][j]));
代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int f[201][51],train1[51][51],train2[51][51],t[51];
int T,n,m1,m2,ans;
int getint()
{
int num=0,flag=1;char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
return num*flag;
}
int main()
{
int i,j,o,k=0;
while((n=getint())!=0)
{
ans=1<<30;
memset(f,0x3f,sizeof f);
T=getint();
for(i=0;i<=T;i++)f[i][1]=i;
for(i=1;i<n;i++)t[i]=getint();
m1=getint();
for(i=1;i<=m1;i++)
{
train1[i][1]=getint();
for(j=1;j<n;j++)train1[i][j+1]=train1[i][j]+t[j];
}
m2=getint();
for(i=1;i<=m2;i++)
{
train2[i][n]=getint();
for(j=n;j>1;j--)train2[i][j-1]=train2[i][j]+t[j-1];
}
for(i=1;i<=T;i++)
for(j=1;j<=n;j++)
{
if(j>1)
{
for(o=1;o<=m1;o++)if(train1[o][j]<=i)
f[i][j]=min(f[train1[o][j-1]][j-1]+i-train1[o][j],f[i][j]);
}
if(j<n)
{
for(o=1;o<=m2;o++)if(train2[o][j]<=i)
f[i][j]=min(f[train2[o][j+1]][j+1]+i-train2[o][j],f[i][j]);
}
}
for(i=0;i<=T;i++)ans=min(f[i][n]+T-i,ans);
printf("Case Number %d: ",++k);
if(ans==0x3f3f3f3f)printf("impossible
");
else printf("%d
",ans);
}
}