• 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;
    
    }
    


    
  • 相关阅读:
    BZOJ1051 [HAOI2006]受欢迎的牛 强连通分量缩点
    This blog has been cancelled for a long time
    欧拉定理、费马小定理及其拓展应用
    同余基础
    [LeetCode] 73. Set Matrix Zeroes
    [LeetCode] 42. Trapping Rain Water
    [LeetCode] 41. First Missing Positive
    [LeetCode] 71. Simplify Path
    [LeetCode] 148. Sort List
    [LeetCode] 239. Sliding Window Maximum
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758871.html
Copyright © 2020-2023  润新知