Uva 1025

题意:

某城市地铁是线性得,有n个车站,从左到右编号为1至n。有M1辆列车从第1站开始往右开,有M2辆列车从第n站开始往左开。在时刻0,Mario从第1站出发,目的是在时刻T会见车站n得一个间谍。在车站等车时容易被抓,所以她决定尽量躲在开动的火车上,让在车站等待的总时间尽量短。列车靠站停车时间忽略不计,并且Mario身手敏捷,即使两辆方向不同的列车在同一时间靠站,Mario也能完成换乘。

分析:

状态:d[i][j]代表时刻i,在车站j,最少的等待时间。边界情况d[T][n]=0,其余的d[T][i]为无穷大,i<T.

       有以下3种决策:

1,原地等待1分钟

2,搭乘往右开的车(如果有)

3,搭乘往左开的车(如果有)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int INF=1e9;
int t[25];
int dp[205][55];
bool has_train[205][55][2];

int main()
{
    //freopen("in.txt","r",stdin);
    int n,T;
    int kase=0;
    while(cin>>n,n)
    {
        memset(has_train,0,sizeof(has_train));
        scanf("%d",&T);
        for(int i=1; i<n; i++)
            scanf("%d",&t[i]);
        t[0]=t[n]=0;
        int M,d;
        scanf("%d",&M);
        for(int i=0; i<M; i++)
        {
            scanf("%d",&d);
            for(int j=1; j<=n; j++)
            {
                d+=t[j-1];
                if(d>T) break;
                has_train[d][j][0]=1;
            }
        }
        scanf("%d",&M);
        for(int i=0; i<M; i++)
        {
            scanf("%d",&d);
            for(int j=n; j>=1; j--)
            {
                d+=t[j];
                if(d>T) break;
                has_train[d][j][1]=1;
            }
        }
        for(int i=1; i<=n-1; 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_train[i][j][0] && i+t[j]<=T)
                    dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]);
                if(j>1 && has_train[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: ",++kase);
        if(dp[0][1]>=INF) printf("impossible
");
        else printf("%d
",dp[0][1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/pach/p/6724495.html