zoukankan      html  css  js  c++  java
  • UVA1025 城市里的间谍 A Spy in the Metro 题解

    这道题是紫书里的,以下的主代码也来自紫书,但笔者会在这里做一些补充说明。

    本题中把单向流逝的时间作为拓补序,用时刻和位置作为状态参数,

    dp【i】【j】表示在i车站,j时刻时还需等待的最少时间(其实通常我们把表示阶段的放在前面)

    边界是这个:
    dp[n][tm]=0;

    for(int i=1;i<n;i++)

    dp[i][tm]=inf;//时间到了,人却不在车站,任务失败

    主代码如下

    for(int j=tm-1;j>=0;j--)
    for(int i=1;i<=n;i++)
    {
    dp[i][j]=dp[i][j+1]+1;
    if(has_train[i][j][0]&&i<n&&j+t[i]<=tm)
    dp[i][j]=min(dp[i][j],dp[i+1][j+t[i]]);
    if(has_train[i][j][1]&&i>1&&j+t[i-1]<=tm)
    dp[i][j]=min(dp[i][j],dp[i-1][j+t[i-1]]);
    }

    第二行其实是可以改成 for(int i=n;i>=1;i--)的,因为

    dp[j+1][ ]的情况都已经打出来了,外循环和内循环的位置不可交换,因为我们的拓补序是时间(逆流的);

     

    关于has_train[ ][ ][ ]我的打法是这样的,过了uva的评测,但是效率较低

    cin>>m1;
    for(int i=1;i<=m1;i++) //T(0≤T≤200) 0 ≤ di ≤ 250
    {
    cin>>tmp;
    has_train[1][tmp][0]=1;
    }
    cin>>m2;
    for(int i=1;i<=m2;i++)
    {
    cin>>tmp;
    has_train[n][tmp][1]=1;
    }
    for(int i=2;i<=n;i++)
    for(int j=t[i-1];j<=tm;j++)
    {
    has_train[i][j][0]=has_train[i-1][j-t[i-1]][0]==1?1:0;
    }

    这是一种很盲的递推,洛谷的题解里有一篇更好的办法:

    for(int i=1; i<=M1; i++){
    int t1;//左站出发时间
    cin>>t1;
    int sum=t1;
    for(int j=1; j<=n; j++){
    trainl[j][sum] = 1;
    sum+=t[j];
    }
    }//谢谢alecli大佬

    题解到此结束

  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/Neptune0/p/11767995.html
Copyright © 2011-2022 走看看