zoukankan      html  css  js  c++  java
  • 题解:UVA1025 A Spy in the Metro

    原题
    pdf

    翻译

    题目大意

    某城市地铁是线性的,有n(2≤n≤50)个车站,从左到右编号1~n。有M1辆列车从第1站开始往右开,还有M2辆列车从第n站开始往左开。列车在相邻站台间所需的运行时间是固定的,因为所有列车的运行速度是相同的。在时刻0,Mario从第1站出发,目的在时刻T(0≤T≤200)会见车站n的一个间谍。在车站等车时容易被抓,所以她决定尽量躲在开动的火车上,让在车站等待的时间尽量短。列车靠站停车时间忽略不计,且Mario身手敏捷,即时两辆方向不同的列车在同一时间靠站,Mario也能完成换乘。

    输入格式

    输入文件包含数种情况,每一种情况包含以下7行:

    第一行是一个正整数n,表示有n个车站 第二行是为T,表示Mario在时刻T见车站n的间谍 第三行有n-1个整数t1,t2,...,tn-1,其中ti表示地铁从车站i到i+1的行驶时间 第四行为M1,及从第一站出发向右开的列车数目 第五行包含M1个正整数a1,a2,...,aM1,即个列车出发的时间 第六行为M2,及从第一站出发向右开的列车数目 第七行包含M2个正整数b1,b2,...,bM2,即个列车出发的时间

    最后一种情况以一行0结尾。

    输出格式

    有若干行,每行先输出“Case Number XXX: ”(XXX为情况编号,从1开始),再输出最少等待时间或“impossible”(无解)。

    Sample Input

    4
    55
    5 10 15
    4
    0 5 10 20
    4
    0 5 10 15
    4
    18
    1 2 3
    5
    0 3 6 10 12
    6
    0 3 5 7 12 15
    2
    30
    20
    1
    20
    7
    1 3 5 7 11 13 17
    0

    Sample Output

    Case Number 1: 5
    Case Number 2: 0
    Case Number 3: impossible

    题解

    这是一道简单的dp题。

    首先,我们发现有一个天然变量(t),因此这必定是一个维度。不难发现,除了时间,影响决策的便只有当前所处的车站了。于是,我们用(f[i][j])表示时间(i),处于(j)站时最少还需要等待的时间。于是,有三种转移到(f[i][j])的方式:

    1. 上次就在(j)站,等了一分钟。
    2. 从左边那站搭乘过来(如果可行)。
    3. 从右边那站搭乘过来(如果可行)。

    为了判别是否可行,我们需要开一个have_train数组来记录某一时刻是否有车。

    代码如下

    #include <cstring>
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    const int maxt=300;
    const int maxn=100;
    const int inf=0x3f3f3f3f;
    
    bool have_train[maxt][maxn][2];
    //have_train[][][0]: 从左往右是否有车, [1]: 从右往左 
    int dp[maxt][maxn];
    int t[maxn];
    int T,n;
    int casee;
    
    inline void init()
    {
        cin>>T;
        memset(have_train,0,sizeof(have_train));
        for(int i=1;i<n;++i) cin>>t[i];
        int M;
        cin>>M;
        while(M--)
        {
            int time;
            cin>>time;
            for(int i=1;i<n;++i)
            {
                time+=t[i];
                have_train[time][i+1][0]=1;//有车来了就记录一下 
            }
        }
        cin>>M;
        while(M--)
        {
            int time;
            cin>>time;
            for(int i=n-1;i;--i)
            {
                time+=t[i];
                have_train[time][i][1]=1;
            }
        }
    }
    
    void solve()
    {
        init();
        memset(dp,0x3f,sizeof(dp));
        dp[0][1]=0;
        for(int i=1;i<=T;++i)
            for(int j=1;j<=n;++j)
            {
                dp[i][j]=dp[i-1][j]+1;//上次就在j站,等了一分钟。 
                if(j>1&&have_train[i][j][0]&&i>=t[j-1]) dp[i][j]=min(dp[i-t[j-1]][j-1],dp[i][j]);
                	//从左边那站搭乘过来
                if(j<n&&have_train[i][j][1]&&i>=t[j]) dp[i][j]=min(dp[i-t[j]][j+1],dp[i][j]);
                	//从右边那站搭乘过来
            }
        printf("Case Number %d: ",++casee);
        if(dp[T][n]>T) puts("impossible");
        else printf("%d
    ",dp[T][n]);
        return;
    }
    
    int main()
    {
        while(cin>>n&&n)
            solve();
        return 0;
    }
    
  • 相关阅读:
    转载JGTM' 2004[MVP]有关AOP的三篇精彩文章
    新增Skin
    发表文章的要求
    自定义UserControl的属性为什么不能在设计时显示在属性窗口中
    .Text学习笔记(一)
    访问类的private或internal成员[转载]
    博客园对发表文章的一些要求
    博客园成立了管理团队
    推荐一篇介绍.NET MetaData的文章
    让大家久等了:终于完成了AOP尝鲜系列之第三部[JGTM'2004 [MVP]文章转载]
  • 原文地址:https://www.cnblogs.com/pfypfy/p/8907192.html
Copyright © 2011-2022 走看看