原题目不好复制,就不贴了!
题目大意:
(紫书的题意)某城市的地铁是线性的,有n(2<=n<=50)个车站,从左到右编号1-n,有M1辆车从1站开始往右开,还有M2两车从第n站开始往左开,在时刻0某人从第一站出发,目的是在时刻T,会见车站n的一个间谍。在车站等车容易被抓,所以他决定尽量在开动的火车上,让在车站等待的总时间尽量的短。列车靠站停车的时间忽略。
输入第一行为n,
第二行为T;
第三行有n-1个整数t1,t2---表示从i->i+1车站的时间
第四行为M1
第五行为M1个数d1---dM1表示各列车的发车时间
第六行 M2
M2个d
题解:
影响决策的只有当前时间和所处的车站,所以d(i,j)表示时刻i,你在车站j(编号1-n)最少还需要多少时间
边界:d[T,n]=0,其他为无穷
d(i,j)能发生的情况
决策一:等一分钟
决策二:搭乘往右的车(如果有)
决策三:搭乘往左的车(有)
因为时间最大为T,且小的时间是有大的时间影响的,因为边界为T,
当时刻t,在车站i的时候还要通过 t[i]和d[i]判断有没有车路过
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int t[55];
int has[2000][55][2];
int dp[250][150];
int main()
{
int N,T;
int M1,M2;
int d;
int k=0;
while(scanf("%d",&N),N)
{
scanf("%d",&T);
memset(has,0,sizeof(has));
t[0]=0;
t[N]=0;
for(int i=1; i<N; i++)
{
scanf("%d",&t[i]);
}
scanf("%d",&M1);
for(int i=0; i<M1; i++)
{
scanf("%d",&d);
for(int j=1; j<=N; j++)
{
has[d+t[j-1]][j][0]=1;
d=d+t[j-1];
}
}
scanf("%d",&M2);
for(int i=0; i<M2; i++)
{
scanf("%d",&d);
for(int j=N; j>=1; j--)
{
has[d+t[j]][j][1]=1;
d=d+t[j];
}
}
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&&has[i][j][0]&&i+t[j]<=T)
{
dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
}
if(j>1&&has[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: ",++k);
if(dp[0][1]>=INF)printf("impossible\n");
else printf("%d\n",dp[0][1]);
}
return 0;
}