• 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;
    }
    
  • 相关阅读:
    Window Phone 8手电筒
    Wp检查手机网络状态
    Wp 导航到手机定位设置页面
    Wp8 读取手机信息
    移动端丨-webkit-overflow-scrolling:touch属性导致页面卡住
    小程序丨canvas内容自适应不同尺寸屏幕
    钉钉自带浏览器版本过低,导致Object.assign不兼容...
    HTTP中GET与POST的区别
    git丨Push rejected: Push to origin/master was rejected
    小程序丨嵌套循环
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5601854.html
Copyright © 2020-2023  润新知