zoukankan      html  css  js  c++  java
  • A Spy in the Metro UVA

    题面:https://vjudge.net/problem/UVA-1025

    思路:

    紫书上的dp入门题,蒟蒻看了好久才看明白,下面就是思路。

    首先要用一个三维数组has_train[i][j][k]表示在i时刻第j个站台是否有从左到右或从右到左的车(k = 0为从左到右,k = 1为从右到左)。

    决策一共有3

    决策1:在站台等一分钟。

    决策2:搭乘向右开的车(如果有)

    决策3:搭乘向左开的车(如果有)

    建立dp数组dp[i][j]

    首先是逆向递推,这也是lrj的思路。

    此时dp[i][j]的定义是在i时刻,从j站台到n站台的最小停留时间。

    从上面的三个决策,我们就可以得到递推式

    dp[i][j] = min(dp[i+1][j],dp[i+t[j]][j+1],dp[i+t[j-1]][j-1])

    因为决策23都是需要条件转移的,所以在转移时要加入判断条件,详细细节可以看下面代码。

    初始化dp[T][n] = 0,最后答案是dp[0][1]

    然后这道题还可以正向推

    这个时候dp[i][j]的含义就是i时刻从1站台到j站台的最小停留时间

    转移方程也对应发生了变化

    dp[i][j] = min(dp[i-1][j],dp[i-t[j-1]][j-1],dp[i-t[j]][j+1])

    要注意我们转移的方向变了所以判断决策23的条件也就变了。

    初始化为dp[0][1] = 0,答案是dp[T][N]

    代码1

    #include <bits/stdc++.h>
    using namespace std;
    int dp[300][100];//时间为i时在j站台到n站台所花费的时间。
    const int INF  = 0x3f3f3f3f;
    bool has_train[300][100][2];//dp[i][j][0],mean there is a train which from left to right in j in i time
                                //dp[i][j][1],mean there is a train which from right to left in j in i time
    int t[100];
    int d1[100],d2[100];
    int main()
    {
        int N,T,M1,M2;
        int ca =1;
        while(scanf("%d",&N)&&N)
        {
            scanf("%d",&T);
            for(int i = 1;i<N;++i)
                scanf("%d",&t[i]);
            scanf("%d",&M1);
            for(int i = 1;i<=M1;++i)
                scanf("%d",&d1[i]);
            scanf("%d",&M2);
            for(int i =1;i<=M2;++i)
                scanf("%d",&d2[i]);
            memset(has_train,false,sizeof(has_train));
            for(int i = 1;i<=N;++i)
                dp[T][i] =INF;
            dp[T][N] = 0;
            for(int i =1;i<=M1;++i)
            {
                int x = d1[i];
                for(int j = 1;j<=N;++j)
                {
                    if(x>T)
                        break;
                    has_train[x][j][0] = true;
                    x+=t[j];
                }
            }
            for(int i =1;i<=M2;++i)
            {
                int x = d2[i];
                for(int j =N;j>=1;--j)
                {
                    if(x>T)
                        break;
                    has_train[x][j][1] = true;
                    x+=t[j-1];
                }
            }
            for(int i = T-1;i>=0;--i)
            {
                for(int j = 1;j<=N;++j)
                {
                     dp[i][j] = dp[i+1][j]+1;//决策1
                     if(j>1&&has_train[i][j][1]&&i+t[j-1]<=T)//决策3
                     {
                         dp[i][j] = min(dp[i][j],dp[i+t[j-1]][j-1]);
                     }
                     if(j<N&&has_train[i][j][0]&&i+t[j]<=T)//决策2
                        dp[i][j] = min(dp[i][j],dp[i+t[j]][j+1]);
                }
    //            cout << i << ": ";
    //            for(int j =1 ;j<=N;++j)
    //                cout << dp[i][j] << " ";
    //            cout << "
    ";
            }
            printf("Case Number %d: ",ca++);
            if(dp[0][1]>=INF)
                printf("impossible
    ");
            else
                printf("%d
    ",dp[0][1]);
        }
        return 0;
    }

    代码2

    #include <bits/stdc++.h>
    using namespace std;
    int dp[300][100];//时间为i时在1站台到j站台所花费的时间。
    const int INF  = 0x3f3f3f3f;
    bool has_train[300][100][2];
    int t[100];
    int d1[100],d2[100];
    int main()
    {
        int N,T,M1,M2;
        int ca =1;
        while(scanf("%d",&N)&&N)
        {
            scanf("%d",&T);
            for(int i = 1;i<N;++i)
                scanf("%d",&t[i]);
            scanf("%d",&M1);
            for(int i = 1;i<=M1;++i)
                scanf("%d",&d1[i]);
            scanf("%d",&M2);
            for(int i =1;i<=M2;++i)
                scanf("%d",&d2[i]);
            memset(has_train,false,sizeof(has_train));
            for(int i = 1;i<=N;++i)
                dp[0][i] =INF;
            dp[0][1] = 0;
            for(int i =1;i<=M1;++i)
            {
                int x = d1[i];
                for(int j = 1;j<=N;++j)
                {
                    if(x>T)
                        break;
                    has_train[x][j][0] = true;
                    x+=t[j];
                }
            }
            for(int i =1;i<=M2;++i)
            {
                int x = d2[i];
                for(int j =N;j>=1;--j)
                {
                    if(x>T)
                        break;
                    has_train[x][j][1] = true;
                    x+=t[j-1];
                }
            }
            for(int i = 1;i<=T;++i)
            {
                for(int j = 1;j<=N;++j)
                {
                     dp[i][j] = dp[i-1][j]+1;//决策1
                     if(j<N&&has_train[i][j][1]&&i-t[j]>=0)//决策3
                     {
                         dp[i][j] = min(dp[i][j],dp[i-t[j]][j+1]);
                     }
                     if(j>1&&has_train[i][j][0]&&i-t[j-1]>=0)//决策2
                        dp[i][j] = min(dp[i][j],dp[i-t[j-1]][j-1]);
                }
    //            cout << i << ": ";
    //            for(int j =1 ;j<=N;++j)
    //                cout << dp[i][j] << " ";
    //            cout << "
    ";
            }
            printf("Case Number %d: ",ca++);
            if(dp[T][N]>=INF)
                printf("impossible
    ");
            else
                printf("%d
    ",dp[T][N]);
        }
        return 0;
    }

     

  • 相关阅读:
    第09组 Alpha冲刺 (6/6)
    第09组 Alpha冲刺 (5/6)
    第09组 Alpha冲刺 (4/6)
    第09组 Alpha冲刺 (3/6)
    第09组 Alpha冲刺 (2/6)
    第09组 Alpha冲刺 (1/6)
    第9组(71) 需求分析报告
    第9组(71) 团队展示
    结对编程作业
    第08组 Alpha冲刺 总结
  • 原文地址:https://www.cnblogs.com/baihualiaoluan/p/12287077.html
Copyright © 2011-2022 走看看