• A Spy in the Metro UVA-1025(dp)


    vjudge链接

    原题链接

    • 分析

    我的第一个动归题哈哈,一开始甚至写成了 dfs 。动归题其实都可以用 dfs ,但是太多的重复计算会导致超时。这个题其实可以以时间为主线,通过两层循环填表来解决。紫书上是逆推的,其实顺推和逆推都可以,逆推更方便。

    刚开始以为 “Trainsmove in both directions: from the first station to the last station and from the last station back to the first station.” 是说车到达终点站后会折返,事实上只是说两个方向的车行驶方向不同而已。车到达终点站后不会折返。

    • AC 代码

    顺推:

    /*
     *lang C++ 5.3.0
     *user Weilin_C
    */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    int main()
    {
        int N, T, station[50], c = 0;
        int rightT[205][25], leftT[205][25], tr, tl;
        int dp[500][50];
    
        while (scanf("%d", &N) && N) {
            int t;
            memset(rightT, 0, sizeof(rightT));
            memset(leftT, 0, sizeof(leftT));
            scanf("%d", &T);
            for (int i = 0; i < N-1; i++)
                scanf("%d", &station[i]);
                scanf("%d", &tr);
                for (int i = 0; i < tr; i++) {
                    scanf("%d", &t);
                    for (int ti = t, st = 0; ti <= T && st < N; st++) {
                        rightT[ti][st] = 1;
                        ti += station[st];
                    }
                }
                scanf("%d", &tl);
                for (int i = 0; i < tl; i++) {
                    scanf("%d", &t);
                    for (int ti = t, st = N-1; ti <= T && st > 0; st--) {
                        leftT[ti][st] = 1;
                        ti += station[st-1];
                    }
                }
    
                //初始化为比 T 大就行,也可以用 memset(dp, 1, sizeof(dp));
                for (int i = 0; i <= T; i++)
                    for (int j = 0; j <= N; j++)
                        dp[i][j] = T+1;
    
                dp[0][0] = 0;
                for (int i = 1; i <= T; i++) {
                    for (int j = 0; j < N; j++) {
                        dp[i][j] = dp[i-1][j] + 1;
                        if (j > 0 && i >= station[j-1] && rightT[i-station[j-1]][j-1]) { //有右向车到达
                            dp[i][j] = min(dp[i][j], dp[i-station[j-1]][j-1]);
                        }
                        if (j < N-1 && i >= station[j] && leftT[i-station[j]][j+1]) { //有左向车到达
                            dp[i][j] = min(dp[i][j], dp[i-station[j]][j+1]);
                        }
                    }
                }
    
                printf("Case Number %d: ", ++c);
                if (dp[T][N-1] > T) printf("impossible
    ");
                else printf("%d
    ", dp[T][N-1]);
        }
    
        return 0;
    }
    

    逆推和紫书上差不多:

                dp[T][N-1] = 0;
                for (int i = T-1; i >= 0; i--) {
                    for (int j = 0; j < N; j++) {
                        dp[i][j] = dp[i+1][j] + 1;
                        if (j < N-1 && i + station[j] <= T && rightT[i][j]) { //有右向车出发
                            dp[i][j] = min(dp[i][j], dp[i + station[j]][j+1]);
                        }
                        if (j > 0 && i + station[j-1] <= T && leftT[i][j]) { //有左向车出发
                            dp[i][j] = min(dp[i][j], dp[i + station[j-1]][j-1]);
                        }
                    }
                }
    
                printf("Case Number %d: ", ++c);
                if (dp[0][0] > T) printf("impossible
    ");
                else printf("%d
    ", dp[0][0]);
    

    by SDUST weilinfox
    原文链接:https://www.cnblogs.com/weilinfox/p/12559058.html

  • 相关阅读:
    webdav srs相关
    How To Configure WebDAV Access with Apache on Ubuntu 14.04
    ubuntu 编译lighttpd
    srs编译及推流测试
    Compile pciutils (lspci, setpci) in Windows x86,在 Windows x86 平台下编译 pciutils (lspci, setpci)
    mingw MSYS2 区别
    Qt之美(三):隐式共享
    Qt之美(二):元对象
    Qt之美(一):d指针/p指针详解
    C++的栈空间和堆空间
  • 原文地址:https://www.cnblogs.com/weilinfox/p/12559058.html
Copyright © 2020-2023  润新知