题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=245&page=show_problem&problem=3466

思路:我写的是填表法,书上写的是刷表法,刚开始因为一个数组叫time,re了好几发

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
const int inf = 0x3f3f3f3f;//1061109567
typedef long long LL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int time1[55];
int train[210][55][2];//0表示往右开有车,1表示往左开有车
int dp[210][55];//表示在时刻i,火车在车站j的所用的最短时间
int main()
{
int n,t;
int cas = 1;
while(scanf("%d",&n) && n)
{
memset(train,0,sizeof(train));
memset(dp,inf,sizeof(dp));
scanf("%d",&t);
for(int i=1; i<n; i++)
scanf("%d",&time1[i]);
int d,m1,m2;
scanf("%d",&m1);
while(m1--)//往右开
{
scanf("%d",&d);
for(int j=1; j<n; j++)
{
if(d <= t)
train[d][j][0] = 1;
d += time1[j];
}
}
scanf("%d",&m2);
while(m2--)
{
scanf("%d",&d);
for(int j=n; j>=2; j--)
{
if(d <= t)
train[d][j][1] = 1;
d += time1[j-1];
}
}
dp[0][1] = 0;
for(int i=0; i<=t; i++)
{
for(int j=1; j<=n; j++)
{
dp[i+1][j] = min(dp[i+1][j],dp[i][j]+1);//等待一秒
if(train[i][j][0] && j < n && i + time1[j] <= t)//往右走
dp[i+time1[j]][j+1] = min(dp[i+time1[j]][j+1],dp[i][j]);
if(train[i][j][1] && j > 1 && i + time1[j-1] <= t)//往左走
dp[i+time1[j-1]][j-1] = min(dp[i+time1[j-1]][j-1],dp[i][j]);
}
}
if(dp[t][n] == inf)
printf("Case Number %d: impossible\n",cas++);
else
printf("Case Number %d: %d\n",cas++,dp[t][n]);
}
return 0;
}