UVa 1025 A Spy in the Metro (DP动态规划)

题意:一个间谍要从第一个车站到第n个车站去会见另一个,在是期间有n个车站,有来回的车站,让你在时间T内时到达n,并且等车时间最短,

也就是尽量多坐车,最后输出最少等待时间。

析:这个挺复杂,首先时间是一个顺序,设d(i,j)表示时刻 i 在第 j 个车站,最少还要等待多长时间,那么边界是d(T, n) = 0。

并且有三种决策:

决策一:等着 d[i][j] = d[i + 1][j] + 1; 为什么从i + 1 过来呢? 你想一下,DP表示等待的时间,那么是不是应该倒着来呢?

决策二:有往右行驶的车  d[i][j] = min(d[i][j],  d[i + t[j]][j];

决策三:有往左行驶的车  d[i][j] = min(d[i][j], d[i + t[j - 1]][j]);

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int INF = 0x3f3f3f3f;

int main(){
    int T, n, t[80], dp[205][60], m1, m2, train[255][55][2], d, k = 0;

    while(scanf("%d", &n) && n){
        scanf("%d", &T);
        t[0] = 0;
        for(int i = 1; i < n; ++i)
            scanf("%d", &t[i]);
        scanf("%d", &m1);
        memset(train, false, sizeof(train));
        for(int i = 0; i < m1; ++i){
            scanf("%d", &d);
//            train[d][1][0] = true;
            int s = d;
            for(int j = 0; j < n; ++j){
                s += t[j];
                if(s <= T)  train[s][j+1][0] = true;
                else    break;
            }
        }

        scanf("%d", &m2);
        for(int i = 0; i < m2; ++i){
            scanf("%d", &d);
            train[d][n][1] = true;
            int s = d;
            for(int j = n-1; j > 1; --j){
                s += t[j];
                if(s <= T)  train[s][j][1] = true;
                else    break;
            }
        }

        for(int i = 1; i < n; ++i)  dp[T][i] = INF;
        dp[T][n] = 0;

        for(int i = T-1; i >= 0; --i)  /// t
            for(int j = 1; j <= n; ++j){  /// g
                dp[i][j] = dp[i+1][j] + 1;
                if(j < n && train[i][j][0] && i + t[j] <= T)
                    dp[i][j] = min(dp[i][j], dp[i+t[j]][j+1]);
                if(j > 1 && 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: impossible
", ++k);
         else printf("Case Number %d: %d
", ++k, dp[0][1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dwtfukgv/p/5601854.html