首页 > 代码库 > UVA 1025 - A Spy in the Metro (DAG的动态规划)

UVA 1025 - A Spy in the Metro (DAG的动态规划)

第一遍,刘汝佳提示+题解;回头再看!!!

POINT:

  dp[time][sta];  在time时刻在车站sta还需要最少等待多长时间;

  终点的状态很确定必然是的 dp[T][N] = 0 ---即在T时刻的时候正好达到N站点

  我们可以 从终点的状态往起始的状态转化, 一步步走就可以了。

  has_train[t][i][0];  t时刻在i车站是否有往右开的火车

  has_train[t][i][1];  t时刻在i车站是否有往左开的火车

 

 

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <deque>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <iomanip>
using namespace std;

#define INF 0xffffff7
#define maxn 200+10

int N, T;
int t[maxn];
int dp[maxn][maxn];//dp[i][j] i时刻在j车站最少等候时间
int has_train[maxn][maxn][2];
int main()
{
    //freopen("out.txt", "r", stdout);
    int kase = 0;
    int N;
    while(scanf("%d", &N) && N)
    {
        memset(has_train, 0, sizeof(has_train));
        memset(t, 0, sizeof(t));
        kase++;
        scanf("%d", &T);
        for(int i = 1; i < N; i++)
            scanf("%d", &t[i]);

        int M1, M2;
        scanf("%d", &M1);
        for(int i = 1; i <= M1; i++)
        {
            int start;
            scanf("%d", &start);
            has_train[start][1][0] = 1;  // 标记初始站台
            for(int j = 1; j < N; j++)
            {
                int time = start + t[j];
                if(time <= T)
                {
                    has_train[time][j+1][0] = 1;
                    start += t[j];
                }
            }
        }
        scanf("%d", &M2);
        for(int i = 1; i <= M2; i++)
        {
            int start;
            scanf("%d", &start);
            has_train[start][N][1] = 1;  // 标记初始站台
            for(int j = N-1; j >= 1; j--)
            {
                int time = start + t[j];
                if(time <= T)
                {
                    has_train[time][j][1] = 1;
                    //cout << "has[" << time << "][" << j << "][1]  " << endl;
                    start += t[j];
                }
            }
        }
        printf("Case Number %d: ", kase);

        for(int i = 1; i < N; i++)
            dp[T][i] = INF;
        dp[T][N] = 0;
        for(int i = T-1; i >= 0; i--)
        {
            for(int j = 1; j <= N; j++)
            {
                dp[i][j] = dp[i+1][j] + 1;  //第T-1时刻在j车站最少等候时间 = 第T时刻在j车站最少等候时间+1; 即决策一---等一分钟
                if(j < N && has_train[i][j][0] && i + t[j] <= T) //决策二
                {
                    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("impossible\n");
        else  printf("%d\n", dp[0][1]);
    }
    return 0;
}