LC1997-访问完所有房间的第一天

题意

  • 这里有 n 个房间,从 0 到 n-1 编号。
  • 你每天访问一个房间,第 0 天访问第 0 号房间。
  • 接下来,你访问房间的【次序】将根据下面的【规则】决定:
    • 假设某一天,你访问 i 号房间。
    • 如果算上本次访问,访问 i 号房间的次数为【奇数】 ,那么 第二天 需要访问 nextVisit[i] 所指定的房间,其中【0 <= nextVisit[i] <= i 】。注意【0 <= nextVisit[i] <= i】,如果访问次数为【奇数】,我们就要回溯。
    • 如果算上本次访问,访问 i 号房间的次数为【偶数】,那么 第二天 需要访问 (i + 1) mod n 号房间。即,访问下一号房间。
  • 求出【访问完所有房间的天数】,模1e9+7。

思路

首先

我们注意到一个事情啊,如果对当前这个房间的访问次数为奇数,那么明天就必须返回更小的房间;如果对当前房间的访问次数为偶数,明天才能堪堪访问紧邻的下一号房间,这样一点一点往前爬。

所以不难想到,【访问完所有房间的天数】就是【访问最后一个房间的天数】。

然后

  • 设 dp[i] 为【第一次访问 i 号房间的天数】。
  • 如果在 dp[i] 这一天第一次访问 i 号房间,那么【i-1 号房间的访问次数】应该是偶数,只有这样才能从 i-1 爬到 i。
  • 那么,我们怎么从 i-2 爬到 i-1的呢?i-2 号房间的访问次数,也需要是偶数。
  • i-3、i-4、……。为了爬到 i 号房间,以前所有房间的访问次数,都需要是偶数。
  • 在 dp[i]+1 这一天,我们返回了 nextVisit[i] 号房间。如果 nextVisit[i]≠i 即 nextVisit[i]<i,除了 i 和 nextVisit[i] 号房间的访问次数是奇数,其他房间全是偶数(包括0次,未访问)。
  • 请集中精神仔细看,关键来了:
  • 我们现在的情况,像不像【刚刚访问 nextVisit[i] 号房间】的情况?也是 nextVisit[i] 刚刚变成奇数,其他房间都是偶数。i>nextVisit[i],对接下来爬到 nextVisit[i]+1 毫无影响。不能说是很像,只能说一模一样!
  • 如果我们想从 i 爬到 i+1,我们需要第二次访问 i 号房间,即,从 nextVisit[i] 爬到 i。我们已经经历一遍这个过程了,就是在第一次访问 i 号房间,从 nextVisit[i] 爬到 i 的过程。
  • 因此,这一段过程需要 dp[i]-dp[nextVisit[i]] 的天数,直接相减。
  • 此时,我们已经第二次到达 i 号房间。再花最后一天爬到 i+1 号房间,我们就又往前进了一步。
  • 总结整个过程:爬到 i,dp[i] 天;从 i 到 nextVisit[i],1 天;从 nextVisit[i] 再次到 i,dp[i]-dp[nextVisit[i]] 天;从 i 到 i+1,1 天。
  • 得到递推方程:dp[i+1]=dp[i]+1+dp[i]-dp[nextVisit[i]]+1
  • 整理:dp[i+1]=2*dp[i]-dp[nextVisit[i]]+2
  • 别急,还有一种情况哦:如果 nextVisit[i]=i 怎么办?公式变成dp[i+1]=dp[i]+2,用 dp[i] 天到达 i,花一天时间原地打转,再花一天时间前进一步,公式也没问题。
  • 所以就 ok 了!

另一种神乎其技的解法

  • 设 f[i] 为【从 第一次访问 i 到 第一次访问 i+1】的天数,即 dp[i+1]-dp[i]。
  • 我们在 dp[i] 这一天访问了 i,下一天会回到 j=nextVisit[i]。我们已经知道,情况和【第一次访问 j=nextVisit[i]】一模一样。
  • 所以,从 j 爬到 j+1,需要 f[j] 天。爬到 j+1 后,j+1 的访问次数变成奇数,而 j 因为【要往前爬】变成偶数。此时,是不是又和【第一次访问 j+1】一模一样了?
  • 所以,从 j+1 爬到 j+2,需要 f[j+1] 天。接下来到 j+3,需要 f[j+2] 天。……。接下来到 i,需要 f[i-1] 天。
  • 我们得到了什么结论?从 j=nextVisit[i] 再次爬到 i,需要 \(\sum_{k=j}^{i-1}f[k]\) 天。加上从 i 到 j=nextVisit[i] 的 1 天、第二次到 i 后再进一步的 1 天,【从 第一次访问 i 到 第一次访问 i+1】需要 \(2+\sum_{k=j}^{i-1}f[k]\) 天。
  • 我们得到了递推方程:\(f[i]=2+\sum_{k=j}^{i-1}f[k]\)。
  • 求和,可以用前缀和去优化。设 \(sum[i]=\sum_{k=0}^{i-1}f[i]\),则sum[i+1]-sum[i]=f[i]=2+sum[i]-sum[j]=2+sum[i]-sum[nextVisit[i]]
  • 整理一下:sum[i+1]=2*sum[i]-sum[nextVisit[i]]+2。好家伙,这不就是那个 dp 的递推公式吗?原来 sum 就是 dp!
  • sum 就是 dp 的考证:我们在第0天访问了 0 号房间。要去访问 i 号房间,天数为 0+【从第一次访问 0 到第一次访问 1,f[0]】+【从第一次访问 1 到第一次访问 2,f[1]】+……+【从第一次访问 i-1 到第一次访问 i,f[i-1]】,可不就是sum[i]嘛!
  • 现在,我们已经完整地了解了,该题的两套解法。

刷题记录:LC1997-访问完所有房间的第一天的更多相关文章

  1. 刷题记录:[De1ctf] shell shell shell

    目录 刷题记录:[De1ctf] shell shell shell 一.知识点 1.源码泄露 2.正则表达式不完善导致sql注入 3.soapclient反序列化->ssrf 4.扫描内网 5 ...

  2. 刷题记录:[ByteCTF 2019]EZCMS

    目录 刷题记录:[ByteCTF 2019]EZCMS 一.知识点 1.源码泄露 2.MD5长度扩展攻击 3.php://filter绕过正则实现phar反序列化 刷题记录:[ByteCTF 2019 ...

  3. 刷题记录:[LCTF]bestphp's revenge

    目录 刷题记录:[LCTF]bestphp's revenge 一.知识点 1.SoapClient触发反序列化导致ssrf 2.serialize_hander处理session方式不同导致sess ...

  4. 刷题记录:[CISCN2019 总决赛 Day2 Web1]Easyweb

    目录 刷题记录:[CISCN2019 总决赛 Day2 Web1]Easyweb 一.涉及知识点 1.敏感文件泄露 2.绕过及sql注入 3.文件上传:短标签绕过php过滤 刷题记录:[CISCN20 ...

  5. 刷题记录:[网鼎杯]Fakebook

    目录 刷题记录:[网鼎杯]Fakebook 一.涉及知识点 1.敏感文件泄露 2.sql注入 二.解题方法 刷题记录:[网鼎杯]Fakebook 题目复现链接:https://buuoj.cn/cha ...

  6. $2019$ 暑期刷题记录1:(算法竞赛DP练习)

    $ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...

  7. PKUWC&SC 2018 刷题记录

    PKUWC&SC 2018 刷题记录 minimax 线段树合并的题,似乎并不依赖于二叉树. 之前写的草率的题解在这里:PKUWC2018 minimax Slay the Spire 注意到 ...

  8. DP刷题记录(持续更新)

    DP刷题记录 (本文例题目前大多数都选自算法竞赛进阶指南) TYVJ1071 求两个序列的最长公共上升子序列 设\(f_{i,j}\)表示a中的\(1-i\)与b中色\(1-j\)匹配时所能构成的以\ ...

  9. DP刷题记录

    目录 dp刷题记录 codeforces 706C codeforces 940E BZOJ3997 POJ2279 GYM102082B GYM102082D codeforces132C L3-0 ...

随机推荐

  1. NODE.JS exports require理解

    node.js exports 的作用是什么? 因为A.js文件想访问B.js文件中的类或函数,是不能直接访问的.为了解决这个问题 node.js 产生了 exports ,exports 实际可以理 ...

  2. 【python基础】第08回 流程控制 for循环

    本章内容概要 1.循环结构之 for 循环 本章内容详解 1.循环结构之for循环 1.1 语法结构 for 变量名 in 可迭代对象: #字符串 列表 字典 元组 for 循环的循环体代码 针对变量 ...

  3. 学习C4C的视频分享

  4. 用 40 块搞个游戏机「GitHub 热点速览 v.22.27」

    作者:HelloGitHub-小鱼干 最便宜的小霸王游戏机都超过了五十,但是现在有了 PicoBoot 你用 40 块的树莓派就能搞出个任天堂游戏机(NGC).PicoBoot 替换了 NGC 的 I ...

  5. PHP生成图形验证码

    在建站过程中,很多时候都会需要用户验证验证码等操作,比如:注册.登录.发表评论.获取资源等等,一方面可以验证当前用户的行为是否是爬虫.机器人等情况,给网站数据统计产生影响:另一方面可以防止用户大量刷取 ...

  6. Zabbix 5.0:通过LLD方式自动化监控阿里云RDS

    Blog:博客园 个人 之前做了RDS监控,由于 RDS 实例梳理增多,手动添加的方式已经不够效率,故改为LLD(Low-level discovery)方式做监控. 什么是LLD LLD(Low-l ...

  7. C语言指针-小结

    1) 指针变量可以进行加减运算,但是指针变量的加减运算并不是加上或减去一个数,而是跟指针指向的数据类型有关,数据类型在系统中占了多少个字节,指针+1后就向后移动了多少个字节. 2) int *poin ...

  8. java。多态

    package Demo.oop.APP.Demo05; public class application { public static void main(String[] args) { //一 ...

  9. MicTR01 Tester 开发套件(振弦采集读数仪)使用说明

    MicTR01 是系列振弦模块 VM5/6/7和电子标签读写模块 TR01 开发测试.开发套件.使用 STC8 位 51 单片机为核心部件,演示上述各个型号模块的基本用法,包括了模块使用时的硬件连接和 ...

  10. Solution -「原创」Destiny

    题目背景 题目背景与题目描述无关.签到愉快. 「冷」 他半靠在床沿,一缕感伤在透亮的眼眸间荡漾. 冷见惆怅而四散逃去.经历嘈杂喧嚣,感官早已麻木.冷又见空洞而乘隙而入.从里向外,这不是感官的范畴. 他 ...