UVA1025-A Spy in the Metro-动态规划

A Spy in the Metro

题意:一人要从一号车站做车去n号车站,输入每两个车站间的通过时间,和两头火车的出发时间,求这个人最少要在车站等多久;

思路:动态规划,仅考虑当前时间和所在车站对结果的影响,dp【T】【i】 表示最少还需要等待多长时间;

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

const int maxn = 55;
const int INF = 0x3f3f3f;
int n,T;
int t[maxn];
int m1,m2;
int train0[55],train1[55],has_train[205][55][2];
int dp[205][55];
int main(){
    int kase=0;
    while(~scanf("%d",&n))
    {    
        memset(has_train,0,sizeof(has_train));
        memset(dp,0,sizeof(dp));
        if(n==0)break;
        scanf("%d",&T);
        for(int i = 1; i <= n-1; i++)
            scanf("%d",&t[i]);
        scanf("%d",&m1);
        for(int i = 1; i <= m1; i++)scanf("%d",&train0[i]);
        scanf("%d",&m2);
        for(int i = 1; i <= m2; i++)scanf("%d",&train1[i]);
        for(int i = 1; i <= m1; i++)
        {
            int tmp = train0[i];
            int id = 1;
            while(tmp <= T)
            {
                has_train[tmp][id][0]=1;
                tmp+=t[id];
                id++;
                if(id>=n)break;
            }
        }
        for(int i = 1; i <= m2; i++)
        {
            int tmp = train1[i];
            int id = n;                //一开始这里写成n-1一直wa;
            while(tmp <= T)
            {
                has_train[tmp][id][1]=1;
                tmp+=t[id-1];
                id--;
                if(id<=1)break;
            }
        }
        for(int i=1;i<=n-1;i++)
            dp[T][i] = INF;
        dp[T][n] = 0;

        for(int i = T-1; i>=0; i--)            //dp核心!
        {
            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)    //has_train[][]表示第i秒在第j个车站是否有火车经过,有->把这个车站的等待时间接到前一个;
                    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]);
            }    
        }
        if(dp[0][1]<INF)
            printf("Case Number %d: %d\n",++kase,dp[0][1]);
        else printf("Case Number %d: impossible\n",++kase);
    }
    return 0;
}

 

posted @ 2018-02-22 17:45  ckxkexing  阅读(127)  评论(0编辑  收藏  举报