• Codeforces Round #604 (Div. 1)


    题意

    给出排成一列的 (n) 个格子,你要从 (1) 号格子走到 (n) 号格子之后(相当于 (n+1) 号格子),一旦你走到 (i+1) 号格子,游戏结束。 当你在 (i) 号格子时,你有 (p_i) 的概率走到 (i+1) 号格子,否则你会返回最近的一个 checkpoint (存档点),最近的存档点是指 (max{x|xleq i ; and ; ischeckpoint(x)}) 。对于每个 (query x) ,会把 (x) 号格子的 checkpoint 属性翻转,然后输出此时从 (1) 号格子走到 (n+1) 号格子的期望步数。

    题解

    考虑没有 checkpoint 的情况,也就是 2E 的题意。此时有两种比较好的解法:

    1. (dp_i) 表示从 (1) 号格子开始,第一次走到 (i) 号格子所需的期望步数,则 (dp_1=0) ,所求为 (dp_{n+1})
      对于 (i+1) 号格子,走到它有两种可能:成功,从 (i) 号格子转移;失败,从 (1) 号格子转移。

      [dp_{i+1}=p_i(1+dp_i)+(1-p_i)(1+dp_i+dp_{i+1}) ]

      化简,即

      [dp_{i+1}=frac{1}{pi}(1+dp_i) ]

      递推可以求解。

    2. (dp_i) 表示从 (i) 号格子开始,第一次走到 (n+1) 号格子所需的期望步数,则 (dp_{n+1}=0) ,所求为 (dp_{1})
      对于 (i) 号格子,下一步有两种可能:成功,转移到 (i+1) 号格子;失败,转移到 (1) 号格子。

      [dp_i=p_i(dp_{i+1}+1)+(1-p_i)(1+dp_1) ]

      则有

      [dp_{n+1}=0 ]

      [dp_n=p_n(dp_{n+1}+1)+(1-p_n)(1+dp_1) ]

      [dp_{n-1}=p_{n-1}(dp_n+1)+(1-p_{n-1})(1+dp_1) ]

      [dp_{n-2}=p_{n-2}(dp_{n-1}+1)+(1-p_{n-2})(1+dp_1) ]

      ...

      [dp_3=p_3(dp_4+1)+(1-p_3)(1+dp_1) ]

      [dp_2=p_2(dp_3+1)+(1-p_2)(1+dp_1) ]

      [dp_1=p_1(dp_2+1)+(1-p_1)(1+dp_1) ]

      每次把上一个式子代到下一个式子,会使得整个式子只带有 (dp_1) 一个未知项,最后把 (dp_1) 解出来就可以了。

    那么加上 checkpoint ,解法出现了一些变化,只说看起来比较好的第一种。

    (dp_i) 表示从 (1) 号格子开始,第一次走到 (i) 号格子所需的期望步数,则 (dp_1=0) ,所求为 (dp_{n+1})
    对于 (i+1) 号格子,走到它有两种可能:成功,从 (i) 号格子转移;失败,从 (x) 号格子转移, (x) 表示 (i) 对应的 checkpoint。
    根据期望的线性性,可得 (cost(x,y)=dp_y-dp_x) ,表示从 (x) 号格子转移到 (y) 号格子的花费为两式的差。

    [dp_{i+1}=p_i(1+dp_i)+(1-p_i)(1+dp_i+cost(x,i+1)) ]

    化简,即

    [dp_{i+1}=frac{1}{p_i}(1+dp_i-(1-p_i)dp_{x}) ]

    [dp_{i+1}=frac{1}{p_i}(1+dp_i+(p_i-1)dp_{x}) ]

    [dp_{i+1}=frac{1}{p_i}+dp_{x}+frac{1}{p_i}dp_i-frac{1}{p_i}dp_{x} ]

    注意到一开始是没有任何 checkpoint 的(就算有也可以逐个添加进来),先按照 2E 的方法解决好。然后插入第一个 checkpoint (x) ,那么显然不比 (x) 大的都是不受影响的。
    第一个受影响的点即 (x+1)

    [dp_{x+1}=frac{1}{p_x}(1+dp_x-(1-p_x)dp_{x}) ]

    化简,即

    [dp_{x+1}=frac{1}{p_x}+dp_{x} ]

    第二个受影响的点即 (x+2) (第一种化简格式):

    [dp_{x+2}=frac{1}{p_{x+1}}(1+dp_{x+1}-(1-p_{x+1})dp_{x}) ]

    代入,即

    [dp_{x+2}=frac{1}{p_{x+1}}(1+frac{1}{p_x}+dp_{x}-(1-p_{x+1})dp_{x}) ]

    化简,即

    [dp_{x+2}=frac{1}{p_{x+1}}(1+frac{1}{p_x}+p_{x+1}dp_{x}) ]

    化简,即

    [dp_{x+2}=frac{1}{p_{x+1}}+frac{1}{p_x p_{x+1}}+dp_{x} ]

    代入第三种化简格式,检验成立

    第三个受影响的点即 (x+3) (第三种化简格式):

    [dp_{x+3}=frac{1}{p_{x+2}}+dp_{x}+frac{1}{p_{x+2}}dp_{x+2}-frac{1}{p_{x+2}}dp_{x} ]

    代入,即

    [dp_{x+3}=frac{1}{p_{x+2}}+dp_{x}+frac{1}{p_{x+2}}(frac{1}{p_{x+1}}+frac{1}{p_x p_{x+1}}+dp_{x})-frac{1}{p_{x+2}}dp_{x} ]

    化简,即

    [dp_{x+3}=frac{1}{p_{x+2}}+frac{1}{p_{x+1} p_{x+2}}+frac{1}{p_x p_{x+1} p_{x+2}}+dp_{x} ]

    假设保存有 (p_i) 的逆元 (invp_i) ,那么这个修改就相当于每个元素依次加上一个前缀积。

  • 相关阅读:
    在VMWare虚拟机下的ubuntu中Samba服务的安装
    Shell表达式,如${file##*/}
    如何从官网下载QT
    SATA命令之security
    Clip
    JS判断是否在微信浏览器打开
    微信小程序请求数据报错: 如若已在管理后台更新域名配置,请刷新项目配置后重新编译项目,操作路径:“详情-域名信息”
    typeof()和instanceof的用法区别
    javascrip 对数组的操作方法
    微信小程序 修改数据,并动态渲染页面;修改数组;
  • 原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12010101.html
Copyright © 2020-2023  润新知