zoukankan      html  css  js  c++  java
  • Luogu P1081 开车旅行 题解报告

    题目传送门

    【题目大意】

    【思路分析】

     这题预处理的部分有点多:

    1.小A和小B从城市$i$出发,行驶到的下一个城市$ga[i]$和$gb[i]$

    详细做法参见例题邻值查找

    2.设$f[i][j][k]$表示从城市$j$出发,行驶了$2^i$天,$k$先开车,最终会到达的城市编号。$k$等于0或1,0表示轮到小A开车,1表示轮到小B开车。

    初始值:$f[0][j][0]=ga[j],f[0][j][1]=gb[j]$

    当$i=1$时,因为$2^0$是奇数,所以从$j$出发开车$2^1$天到达的城市,等于$k$先开$2^0$天,另一个人$1-k$再开$2^0$天到达的城市,即

    $$f[1][j][k]=f[0][f[0][j][k]][1-k]$$

    当$i>1$时,因为$2^{i-1}$是偶数,所以前后两段路都轮到$k$先开车,即

    $$f[i][j][k]=f[i-1][f[i-1][j][k]][k]$$

    具体实现时要注意$ga,gb,f$数组到达的城市超过第$N$个城市的边界的情况。

    3.设$da[i][j][k]$表示在此状态下,小A行驶的路程总长度。

    初始值:$da[0][j][0]=dist[j][ga[j]],da[0][j][1]=0$

    当$i=1$时

    $$da[1][j][k]=da[0][j][k]+da[0][f[0][j][k]][1-k]$$

    当$i>1$时

    $$da[i][j][k]=da[i-1][j][k]+da[i-1][f[i-1][j][k]][k]$$

    $db[i][j][k]$也同理可得。

    接下来才算进入正题,设$calc(S,X)$表示“从城市$S$出发最多行驶$X$公里”时,A和B分别行驶了多长的路程。

    我们用倍增的思想来解决问题:

    1.初始化当前城市$p=S$,小A、小B累计行驶路程$la=0,lb=0$

    2.倒序循环$i=log_2N~0$

    3.对于每个$i$,若两人从$p$出发行驶$2^i$天,累计路程仍未超过$X$,即$la+lb+da[i][p][0]+db[i][p][0]le X$,则令$la=la+da[i][p][0],lb=lb+db[i][p][0],p=f[i][p][0]$

    4.循环结束后,$la,lb$即为问题的答案

    对于问题一,枚举起点$S_i$,取A、B行驶路程比值较小的$calc(S_i,X_0)$,即可求出问题一答案。

    对于问题二,多次询问$calc(S_i,X_i)$,也可以直接计算。

    整个算法的时间复杂度为$O((N+M)log_2N)$

    【代码实现】

  • 相关阅读:
    SQL语句大全
    SQL SERVER 用sql语句将一列数据拼接成一个字符串
    常用 SQl 语句大全
    巧用一条SQL语句实现其它进制到十进制转换
    sql 2005
    sql convert(varchar(10),getdate(),120)
    sqlserver 日期函数
    转:DBCC CHECKDB 数据库或表修复
    Linux下使用SFTP命令
    mySQL 教程 第7章 存储过程和函数
  • 原文地址:https://www.cnblogs.com/THWZF/p/11230154.html
Copyright © 2011-2022 走看看