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。

  • 相关阅读:
    mssql索引视图无法对视图创建 索引,因为该视图未绑定到架构
    说说回车键触发表单提交的问题
    在C#中使用SqlDbType.Xml类型参数
    使用nginx实施负载均衡
    SQL Server 索引中include的魅力(具有包含性列的索引)
    群发“站内信”的实现
    ORM映射框架总结终极JSON
    51 地图基本接口(二)
    通用短信平台接口
    ORM映射框架总结Flash 处理
  • 原文地址:https://www.cnblogs.com/lfri/p/9439791.html
Copyright © 2011-2022 走看看