zoukankan      html  css  js  c++  java
  • 动态规划初步--城市里的间谍

    一、题目

    某城市的地铁是线性的,有n(2 ≤ n ≤ 50)个车站,从左到右编号为1~n。有M1辆车从第一站开始往右开,还有M2辆从第n站开始往左开。在时刻0,Mario从第一站出发,目的是在T时刻会见在n站的一个间谍。要求其在车站的等待时间足够短。

    二、解题思路

    状态由当前时间和当前所在站决定,我们可以用dp[i][j]表示在时刻t,第i站最少还需要等待的时间。易只T时刻的情况容易确定,

    dp[T][j] = (j == n ? INF : 0),而T时刻之前的dp值,可以由T时刻及其之后的决定。

    即dp[i][j] = max(dp[i][j] + 1,dp[i + t[j]][j + 1],dp[i + t[j - 1][j - 1]]) (加入三种选择都存在时)

    根据状态转移方程和边界值,我们就可以从下至上填满整个表格,dp[0][1]就是要求的。

    三、代码实现

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<stdbool.h>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int maxn = 50 + 10;
    10 const int maxt = 200 + 10;
    11 int n, T, cost_time[maxn],M1,M2;
    12 int dp[maxt][maxn];  //dp[t][i]表示在时刻t,第i站最少还需要等待的时间
    13 int has_train[maxt][maxn][2];  //has_train[i][j][0]表示i时刻,在j车站有开往左的火车,has_train[i][j][1]表示i时刻,在j车站有开往右的火车
    14 int kase = 1;
    15 
    16 void slove()
    17 {
    18     memset(dp, 0, sizeof(dp));
    19     
    20     for (int i = 1; i <= n - 1; i++)  dp[T][i] = INF;    //时刻T,在非n的站,是不可能的,把等待时间设置为无穷大
    21     dp[T][n] = 0;        //时刻T,在第n站,等待时间为0 
    22 
    23     for (int  i = T- 1; i >=  0; i--)
    24     {
    25         for (int j = 1; j <= n; j++)
    26         {
    27             dp[i][j] = dp[i + 1][j] + 1;
    28             if (j < n && has_train[i][j][1] && i + cost_time[j] <= T)
    29                 dp[i][j] = min(dp[i][j], dp[i + cost_time[j]][j + 1]);
    30             if (j > 1 && has_train[i][j][0] && i + cost_time[j - 1] <= T)
    31                 dp[i][j] = min(dp[i][j], dp[i + cost_time[j - 1]][j - 1]);
    32         }
    33     }
    34     printf("Case Number %d: ", kase++);
    35     if (dp[0][1] >= INF)  printf("impossible
    ");
    36     else  printf("%d
    ", dp[0][1]);
    37 }
    38 
    39 int main()
    40 {
    41     while (scanf("%d",&n) == 1 && n)
    42     {
    43         memset(has_train, 0, sizeof(has_train));        //这里必须清零
    44         scanf("%d", &T);
    45         for (int i = 1; i < n; i++)
    46             scanf("%d", &cost_time[i]);
    47 
    48         scanf("%d", &M1);
    49         int start;
    50         for (int i = 0; i < M1; i++)
    51         {
    52             scanf("%d", &start);
    53             int tmp = 0;
    54             for (int j = 1; j <= n && start + tmp <= T; j++)    //只需考虑T之内的
    55             {
    56                 has_train[start + tmp][j][1] = true;
    57                 if(j != n)  tmp += cost_time[j];        //cost_time不能取到n
    58             }
    59         }
    60 
    61         scanf("%d", &M2);
    62         for (int i = 0; i < M2; i++)
    63         {
    64             scanf("%d", &start);
    65             int tmp = 0;
    66             for (int j = n; j >= 1 && start + tmp <= T; j--)
    67             {
    68                 has_train[start + tmp][j][0] = true;
    69                 tmp += cost_time[j - 1];
    70             }
    71         }
    72         
    73         slove();
    74     }
    75     return 0;
    76 }

    四、经验

    ctime变量与标准库里自带的冲突了;之前数组开小了,导致Runtime error。

  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/lfri/p/9439791.html
Copyright © 2011-2022 走看看