A Spy in the Metro Uva-1025

题意:某城市的地铁是线性的,有n(2≤n≤50)个车站,从左到右编号为1-n。有M1辆列车从第1站开始往右开,还有M2辆列车从第n站开始往左开。在时刻0,Mario从第1站出发,目的是在时刻T(0≤T≤200)会见车站n的一个间谍。在车站等车时容易被抓,所以她决定尽量躲在开动的火车上,让在车站等待的总时间尽量短。列车靠站停车时间忽略不计,且Mario身手敏捷,即使两辆方向不同的列车在同一时间靠站,Mario也能完成换乘。
输入第1行为n,第2行为T,第3行有n-1个整数t1,t2,…,tn−1(1≤ti≤70),其中ti表示地铁从车站i到i+1的行驶时间(两个方向一样)。第4行为M1(1≤M1≤50),即从第1站出发向右开的列车数目。第5行包含M1个整数d1, d2,…, dM1(0≤di≤250,di<di+1),即各列车的出发时间。第6、7行描述从第n站出发向左开的列车,格式同第4、5行。输出仅包含一行,即最少等待时间。无解输出impossible。

思路:时间是顺序的,影响因素是某一时刻车在哪一个车站,所以建立dp[i][j]表示在第i秒内在第j个车站所等待的时间最少。train[i][j][0]表示在第i秒第j个车站可不可以向右走,可以为真,不可以为假,train[i][j][1]表示从n->1方向移动。在每一个车站有3种可能:1、原地等2、向右乘车(如果可以)3、向左乘车(如果可以)

#include<iostream>
#include<vector>
#include<algorithm>
#include <cstdio>
#include<cmath>
#include<set>
#include<queue>
#include<cstring>
#include<string>
#include<iomanip>
#define INF 0x3f3f3f
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=2100;
const double PI=acos(-1.0);
const int maxnn = 1e6;
int T,m1,m2;
int dp[maxn][maxn];
int train[maxn][maxn][2];
int t[maxn];
int main()
{
    int n;
    int k=0;
    while(cin >> n && n != 0)
    {
        cin >> T;
        //memset(t,0,sizeof(t));
        t[0] = 0;
        for(int i = 1;i < n;i++)
        {
            cin >> t[i];
        }
        cin >> m1;
        memset(train,0,sizeof(train));
        for(int i = 0;i < m1;i++)
        {
            int d;
            cin >> d;
            int s = d;
            for(int j = 0;j < n;j++)
            {
                s += t[j];
                if(s <= T)train[s][j+1][0] = 1;
                else
                    break;
            }
        }
        cin >> m2;
        for(int i = 0;i < m2;i++)
        {
            int d;
            cin >> d;
            train[d][n][1] = 1;
            int s = d;
            for(int j = n-1;j > 1 ;j--)
            {
                s += t[j];
                if(s <= T)train[s][j][1] = 1;
                else
                    break;
            }
        }
        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 && train[i][j][0] && i + t[j] <= T)\\向右
                    dp[i][j] = min(dp[i][j],dp[i+t[j]][j+1]);
                if(j > 1 && train[i][j][1] && i + t[j-1] <= T)\\向左
                    dp[i][j] = min(dp[i][j],dp[i+t[j-1]][j-1]);
            }
        }
        if(dp[0][1] >= INF) printf("Case Number %d: impossible\n", ++k);
        else printf("Case Number %d: %d\n", ++k, dp[0][1]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/kayiko/p/10798039.html
今日推荐