UVA 1025_A Spy in the Metro

【题意】(小紫书)一个人从站台1出发,乘车要在时刻T到达站台n,为使在站台等车时间最短,她可以选择乘坐两个方向的列车,并在客车停靠站的时候换车。

【分析】每次停站下车时,她都有三种选择,1.原地不动 2.搭乘向右的车 3.搭乘向左的车。d[i][j]表示在站台i,时刻j的最小等待时间。

状态转移方程:

 等待:dp[i][j]=dp[i][j+1]+1;

如果有向右的车:  dp[i][j]=min(dp[i][j],dp[i+1][j+t[i]]);

如果有向左的车: dp[i][j]=min(dp[i][j],dp[i-1][j+t[i-1]]);

注意:

1.某时刻某车站是否有车,可以使用一个三维数组has_train来记录。

2.边界条件  dp[N][T]=0

【代码】

#include<cstdio>
#include<cstring>
#define min(a,b)  (a)<(b)?(a):(b)
const int maxn=250;
const int INF=0xfffffff;
int has_train[55][250][2];
int t[250];
int d[55];
int e[55];
int dp[50][200];
int main (void)
{
    int N,T,total,M1,M2,c=0;
    while(scanf("%d",&N)==1&&N)
    {
        memset(has_train,0,sizeof(has_train));
        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",&d[i]);
            total=0;
            has_train[1][d[i]][0]=1;
            for(int j=1;j<=N-1;j++)
            {
                total+=t[j];
                if(d[i]+total<=T)
                     has_train[j+1][d[i]+total][0]=1;
                else break;
            }
        }
        scanf("%d",&M2);
        for(int i=1;i<=M2;i++)
        {
            scanf("%d",&e[i]);
            total=0;
           has_train[N][e[i]][1]=1;
            for(int j=N-1;j>=1;j--)
            {
                total+=t[j];
                if(e[i]+total<=T)
                    has_train[j][e[i]+total][1]=1;
                else break;
            }
        }
        for(int i=1;i<=N;i++)
            for(int j=0;j<=T;j++)
                dp[i][j]=INF;
        dp[N][T]=0;
         for(int j=T-1;j>=0;j--)
        {
            for(int i=1;i<=N;i++)//i车站j时刻
            {
                dp[i][j]=dp[i][j+1]+1;
                if(j+t[i]<=T&&has_train[i][j][0]&&i<N)
                    dp[i][j]=min(dp[i][j],dp[i+1][j+t[i]]);
                if(j+t[i-1]<=T&&has_train[i][j][1]&&i>1)
                    dp[i][j]=min(dp[i][j],dp[i-1][j+t[i-1]]);
            }
        }
        if(dp[1][0]>=INF)
                printf("Case Number %d: impossible
",++c);
            else
                printf("Case Number %d: %d
",++c,dp[1][0]);
    }
    return 0;

}



原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758870.html