[题解汇总]邓老师部分题目
一道一道地写了......因为有点多,所以可能不是特别详细。另外,这个题解只覆盖我来得及做的,还有很多题我并没有做qwq
[DATALOST]STARS
不得不说,“锦囊” 这个比喻的确十分恰当,但是恰当有什么用,我还是差点没学懂,这道题的启发并不全在于 \(k\) 很小,更重要的是 —— 状态的设计是源于我们对一个序列合法性的判断方式。
◆ 搞定判断
有没有什么方法可以很好地搞定一个序列是否是 “奇妙” 的?注意到 \(k\le 5\),我们可以稍微暴力一点 —— 不妨将固定点 \(P\) 的维数的顺序用 \(\mathcal O(k!)\) 先全部枚举出来,得到一个 \(\set{s_i}\),它描述的是,我们对这个序列从左到右匹配,当某个时候我们发现当前的点 \(A\) 在所确定的 \(P\) 坐标之内没有和它相同的时候,我们打开 \(\set {s_i}\) 的下一维,假设为 \(s_j\),然后我们将 \(A\) 的坐标向量 \(\Vec{v_A}\) 的第 \(s_j\) 维放到 \(\Vec {v_P}\) 的 \(s_j\) 维上。那么,一个序列是合法的,当且仅当存在一个 \(\set {s_i}\) 使得这个序列可以被全部匹配完。
“这就好比有一个世外高人给了你一个锦囊序列,你每遇到一个无法解决的问题的时候,就打开下一个锦囊,看看那个高人给你的指点在哪一维上。
如果锦囊用完了都还有问题,那就说明这个高人是假的。” —— 邓老师
◆ 得到 DP
我们称一个需要启用锦囊的位置为 “失配点”。上面的判断给了我们启发:我们 只需要求出对于一个起始点 \(i\) 以及一个锦囊序列 \(S\) 的失配点集合 \(\mathscr P(i,S)\),举个例子,出门的点 \(i\) 一定在 \(\mathscr P\) 中。
现在,我们尝试寻找 \(\mathscr P(i,S)\) 与 \(\mathscr P(i+1,S[1:])\) 之间的联系 —— 我们先考虑 \((i+1,S[1:])\) 的过程:从 \(i+1\) 开始,先启用 \(S[1]\),再启用 \(S[2]\)...... 而 \((i,S)\) 的过程呢?出门先将 \(S[0]\) 花在了 \(i\) 点上,然后从 \(i+1\) 开始,尝试用 \(S[1:]\) 解决问题,这和 \((i+1,S[1:])\) 十分相似!但是稍微有一些区别:\((i+1,S[1:])\) 无法解决的一些点,可能在 \((i,S)\) 可以通过 \(\Vec {v_i}\) 的第 \(S[0]\) 维解决,因此,我们来一个分类讨论:
- \(\mathscr P(i+1,S[1:])\) 中任何一个点都无法被 \(\Vec{v_i}(S[0])\) 解决,此时 \((i,S)\sim (i+1,S[1:])\);
- \(\mathscr P(i+1,S[1:])\) 中有一个点可以被 \(\Vec{v_i}(S[0])\) 解决,此时,我们找到那个可以被 \(\Vec{v_i}(S[0])\) 解决的点在 \(\mathscr P(i+1,S[1:])\) 中的位置,并将 \(S[0]\) 放到对应的 \(S[1:]\) 中去,得到 \(T\),此时 \((i,S)\sim (i+1,T)\) —— 它稍微有一点类似于,原本我们应当在 \(i\) 就把 \(\Vec{v_i}(S[0])\) 填到 \(\Vec{v_P}\) 中去,不过我们稍微往后延迟了一点;
此时,我们就会转移了:第一个情况的转移是朴素的,直接继承 \(\mathscr P\) 即可,对于第二种情况,考虑在 \(\mathscr P(i+1,S[1:])\) 找到第一个和 \(\Vec{v_i}\) 在 \(S[0]\) 维相同的位置,将那个位置删去,在最开始放入 \(i\) 作为失配点,就完成了转移。
[PA 2021 Round1 A]Od Deski Do Deski
和上一道题相似的思路,我们先考虑判断一个序列是否合法:定义 \(f(i)\) 为 \(a[1:i]\) 的合法性,不难得到转移:
现在开始考虑如何统计这个题的方案,不难发现,一个点 \(i\) 能填入的颜色种类实际上就是满足 \(f[j-1]=1\) 的那些位置的颜色集合。因此,我们可以设计状态 \(dp(i,j,0/1)\) 表示当前位置 \(i\),合法的颜色种数有 \(j\),当前序列 合法/不合法 的方案数。
[DATA LOST]GUESS
注意题目传达的意思是,我们和 \(\textsf{Bob}\) 都不知道 \(y\) 是多少,我们是站在最坏的角度考虑我们可能会需要多少次来猜出答案。
真的无法想到这种转化:如果 \(\textsf{Bob}\) 问 是不是大于 \(x\) ? \(\textsf{Alice}\) 回答是,我们就把 \([1,x]\) 覆盖一遍,否则把 \([x+1,n]\) 的覆盖一遍,而如果一个数被覆盖了大于等于 \(2\) 次,就不可能是这个数。而 \(\textsf{Bob}\) 胜利的情况就是只有一个数覆盖次数小于等于一次。此时,问题就转化为覆盖。这种瞎**转化谁**想得到?
注意到我们每次都是将 \([1,x]\) 或者 \([x,n]\) 覆盖次数加一,因此,覆盖次数构成的函数图像一定是一个形如 "V" 的峡谷,而峡谷两边,过高(指覆盖次数大于等于 \(2\))的部分又会被我们砍掉,因此,可能出现的情况就只有 \([1,1,\cdots,1,0,0,\cdots,0,1,1,\cdots,1]\),那么,我们可以设 \(f(i,j,k)\) 表示 \(\displaystyle [\overbrace{1,1,\cdots,1,1}^{i\;\text{times}},\overbrace{0,0,\cdots,0}^{j\;\text{times}},\overbrace{1,1,\cdots,1,1}^{k\;\text{times}}]\) 的情形还需要最少多少次询问。注意这里我们并没有再可以强调 \(\textsf{Alice}\) 说谎的情况,因为巧妙的转化已经帮助我们解决了。朴素的 DP 复杂度是 \(\mathcal O(n^4)\) 的,不过可以二分决策点,将复杂度降低至 \(\mathcal O(n^3\log n)\),注意到答案关于 \(k\) 是单调的,而次数的大小在 \(\mathcal O(\log)\) 级别,所以我们可以把次数放进状态而将 \(k\) 变成值。最后的复杂度就变成 \(\mathcal O(n^2)\) 了。这一段我还没搞懂,找时间再看看
[PA2021 Round2 A]Poborcy Podatkowi
◆ 暴力的思路
不妨设 \(f(i,j)\) 表示我们在当前的子树中选择了某些长度为 \(4\) 的路径,同时有一条以 \(i\) 为根,长度为 \(j\) 的路径时的最大的和。如果我们不考虑在 \(i\) 上吊的这条路径,转移就是在子树中找一些 \(f(v_k,j_k)\) 使得
- \(j_k=1\) 与 \(j_k=3\) 一样多;
- \(j_k=2\) 的数量为偶数;
求最大权值和,我们只需要在儿子中进行 DP,转移记录 \(dp(\Delta,0/1)\) 表示 \(cnt_1-cnt_3=\Delta\),同时 \(j_k=2\) 的数量为 偶数/奇数 时的最大权值和。
还有一个小问题 —— 我们如何解决 \(i\) 上有一个长度为 \(j\) 的链?这很好办,加一个假儿子 \(x\),并且 \(f(x,4-j)=0\),而 \(f(x,\text{otherwise})=-\infty\) 即可。
不难发现,对于某个点的复杂度是 \(\mathcal O(2\max\Delta)\) 的,总体复杂度将会达到 \(\mathcal O(n^2)\),这不好 😦
◆ 随机的魅力
还记得以前考过一个题,其复杂度也和 \(\Delta\) 有关,而当时的处理是引入随机化降低复杂度然而很多人直接卡常过掉了......,我们不妨故技重施,将儿子们全部都随机化一下,\(\max\Delta\) 就不会特别大,将其限制在 \(\sqrt n\) 以内,总时间复杂度就降低为 \(\mathcal O(n\sqrt n)\) 了。不过这个期望 \(\sqrt n\) 我并不是特别会证= =+
我补了一个证明:关于一个期望根号的证明.
[Snackdown 2021 Final]Queue At The Bakery
◆ 关键的性质
神 TM 注意力比较集中就可以观察到我们可以把所谓 “排队” 想象成是将每个人分配给每个员工,直觉上讲,将所有人平均分配给每个员工,他们的总等待时间将会最小,事实上,我们也一定存在一种平均的分配方案使得总等待时间最小,而这一性质的基础是,所有顾客的服务时间正好都是 \(d\) 秒。该结论的证明不难,然鹅我不知道如何从较 “数学” 的角度说明这个问题。
一个教训,抓住直觉上的一些东西并对其分析,考察其合理性。
◆ 根据性质设计 DP
既然我们知晓了这个性质,那么我们就紧贴 “余数” 来对每一个员工计算其处理的顾客的总等待时间:设 \(f(i,j,r)\) 表示还剩 \(i\) 天,前一个处理的顾客还需要 \(j\) 时间处理完毕,当前顾客的余数为 \(k\),那么就有转移:
- 当 \(k=0\) 时,接待这个顾客,其等待时长为 \(j\),状态变为 \(f(i-1,j+d-1,m-1)\);
- 当 \(k\neq 0\) 时,不用接待这个顾客,状态变为 \(f(i-1,j-1,k-1)\);
- 当没有来人时,编号不变,状态变为 \(f(i-1,j-1,k)\);
但是它的复杂度不优,因为第二维的最大值可能为达到 \(nd\) 级别。但是这也到了一个玄学的地方了,即我们不难发现一个东西:当 \(j>n\) 之后,显然后到的人绝没有可能出现遇到 “到了就可以服务” 的情况,他们只会等到前面所有人都服务完才到他们,因此,假设此时期望有 \(g(i,k)\) 个人,设当前状态 \(j=n+t\),那么将会有 \(f(i,j,k)=f(i,n,k)+(j-n)g(i,k)=f(i,n,k)+t\cdot g(i,k)\),不难看出,这是一个关于 \(j\) 的一次函数。而出现这种情况只有可能在 \(d\) 比较大的时候,当 \(d\) 较小时,几乎不会出现 \(j>n\) 的情况,我们只需要在 \(j\le n\) 以内做即可。
但是这样复杂度达到 \(\mathcal O(n^2d)\),还是不大对,我们发现,实际上并不需要将 \(j\) 按照 \(n\) 区分,大概在 \(S=500\sim 1500\) 的范围内即可,为什么呢?注意到 \(0.4\le p\le 0.6\),也就是说,\(d\) 大概大于等于 \(10\) 时,后到的人遇见 “到了就可以服务” 的概率是十分小的。而函数如果不是关于 \(j\) 线性的,那么有一个时候它会 “触底”,即 \(j=0\),而这种概率在 \(j\) 达到 \(S\) 的数量级后将会小到几乎不影响精度的情况。同样,当 \(d<10\) 时,让 \(j\) 这一维能够积累到 \(S\) 的数量级以上的概率也很小,可以忽略。
于是,复杂度就变成了 \(\mathcal O(nSm)\),如果 \(\color{yellow}{\rm TLE}\) 了,可以考虑调整一下 \(S\).
这里的另一个教训 —— 讨论概率问题的时候,注意哪些情况概率小到对答案没有影响,便可以忽略它。
经本人实测,该阈值设为 \(S=100\) 居然都没什么影响,所以它到底是怎算的啊......
[Snackdown 2021 Final]Robbery
如果我们选择了 \(2m\) 个物品,那么一定存在一种方案,使得划分的两组各 \(m\) 个物品的重量差不超过 \(n\). 那么我们可以设计 DP 状态 \(f(k,w)\) 表示我们选择了 \(k\) 个物品,总重量为 \(w\) 的最大值,根据 \(k\) 的奇偶性分成两种转移:
最多只会有 \(\mathcal O(2\log k)\) 层,并且每层每个节点处理的复杂度为 \(\mathcal O(n)\),而每层的状态数不会超过 \(\mathcal O(5n)\),最后的复杂度就是 \(\mathcal O(n^2\log k)\).
[AGC044E]Random Pawn
只能说特别妙了,第一步都把我妙到了......设 \(f(i)\) 为位置 \(i\) 的答案,那么有
然后就是破环为链的神奇操作:显然 \(f(i)\le \max A_i\)(无论你怎么证明都可以),于是我们可以令 \(A_1=A_{n+1}=\max A_i\),同时就会有 \(f(1)=f(n+1)=A_1\),显然如果走到 \(\max A_i\) 就会停止转移(因为这样是最优的),因此,我们用 \(A_1=A_{n+1}=\max A_i\) 成功破环为链了,现在我们将这个东西转成了一个链上问题,目的是块速求出 \(f(i)\).
接下来是转化成凸包的第二个神奇操作:观察上式,如果没有 \(-B_i\) 这个东西,比如设 \(\displaystyle g(i)=\max\brak{\frac{g(i-1)+g(i+1)}{2},A'_i}\),那么 \(g(i)\) 就会构成一个上凸壳,现在就看我们如何构造这个 \(g(i)\) 了。
注意到我们的 \(B_i\) 和 \(\displaystyle \frac{f(i-1)+f(i+1)}{2}\) 的部分是线性构成的,因此,我们构造的 \(g(i)\) 一定是 \(f(i)\) 与 \(B_i\) 独立构成的,故我们可以设 \(g(i)=f(i)-c(i)\),然后带入原式:
因此,如果 \(c(i-1)+c(i+1)=2(B_i+c(i))\),我们就不用考虑 \(B_i\) 的影响,转而维护一个上凸壳了。而维护这样一个上凸壳复杂度仅仅只有 \(\mathcal O(n)\).
至于这个 \(c(i)\) 怎么求,我们很容易将上式化成 \(c(i+1)=2(B_i+c(i))-c(i-1)\) 的二项递推,随便指定初值即可。复杂度也只有 \(\mathcal O(n)\).
这个题直接秀我一脸......