CF1801D The way home

发布时间 2023-09-25 10:23:19作者: FOX_konata

原题

翻译

非常好的一个题,有两种做法


方法1:flody+dp

首先我们确定一个最优行走方案:从 \(1\) 号节点赚到足够钱后通过最短路到达 \(x_1\) ,在 \(x_1\) 赚够足够钱后到达 \(x_2\) ,在 \(x_2\) 赚够足够钱后到达 \(x_3\) ,如此往复后到达终点

现在我们有一个问题:从 \(u\)\(v\) 的路径,到达 \(v\) 点后有许多结局。我们考虑一个非常朴素的 \(dp\)\(dp_{i,j}\) 表示走到 \(i\) 号点,剩余钱为 \(j\) 的最少表演次数,但这很明显会 \(TLE\) ,寄

但我们发现我们还有一个东西没用:每个点的权值。我们考虑通过转移顺序优化 \(dp\) ,我们用二元组 \(dp_i = (f,g)\) 表示走到 \(i\) 号点,表演 \(f\) 次且最少表演次数为 \(j\) 。这么做 \(dp\) 很明显是不对的,因为我们不知道 \(f\)\(g\) 优先从哪个转移。但我们如果把 \(w_i\) 从小到大排个序,按照顺序考虑,那这个 \(dp\) 就对了

因为我们考虑假如当前 \(v\) 点的 \(dp\) 值的前驱是从 \(u_1\) 转移过来的,我们现在在考虑 \(u_2\)\(v\) 的贡献,因为我们按照点权大小排了序,则我们可以保证 \(w_{u_1} \leq w_{u_2}\) ,这有什么好处呢?这说明如果出现了 \(f_2 > f_1\) ,则无论 \(g\) 的大小关系如何,我们都会选择用 \(u_2\) 更新。因为 \(g_1 < w_{u_1}\) ,我们让这个人在 \(u_2\) 点赚钱 \(f_2 - f_1\) 次,赚得的钱数 \((f_2-f_1)w_{u_2} \geq w_{u-1} > g_1\) ,因此我们从 \(u_2\) 转移更优。

但是还没完,如果 \(f_1 = f_2\) ,则我们优先考虑 \(g\) 更大的即可

因此我们只需要对图 \(O(n^3)\) 的跑一边 \(flody\) 即可解决问题

最终复杂度 \(O(n^3 + n^2 + n \log {n})\) ,复杂度瓶颈在于 \(flody\)


方法2:dijkstra + dp

我们考虑朴素 \(dp\) ,设 \(dp_{i,j,k}\) 表示走到 \(i\) 点的路径上经过的最小点权的点为 \(w_j\) ,还剩 \(k\) 元的最少赚钱次数。这个 \(dp\) 显然会 \(TLE\) ,因此我们考虑优化他。同上一个做法,我们设 \(dp_{i,j} = (f,g)\) 。然后同样的,我们把 \(f\) 当作第一关键字, \(g\) 当作第二关键字即可。注意,这里并不需要排序,因为我们在 \(dp\) 的状态里记录了上一个转移的点,对于 \(j\) 相同的 \(dp\) 状态, \(w_j\) 的值显然是相同的。

因此我们直接用 \(dijkstra\) 优化 \(dp\) 转移即可

最终复杂度 \(O((n^2 + nm) \log n)\)