DP1

DP1

P2523 [HAOI2011] Problem c

从后往前考虑,容易判掉无解。

启发我们计数也从后往前考虑,设 \(f[i][j]\) 表示考虑到 \([i, n]\) 的位置,确定了 \(j\) 个人的编号的方案数。

转移枚举之前确定了多少个人、在当前位置确定多少个人即可。

CF311B Cats Transport

求出正好接到每只小猫的出发时间 \(a_i\),将小猫 \(a\) 升序排序,记 \(s_i\)\(a\) 的前缀和,朴素的 dp 转移:设 \(f_{i, j}\) 表示考虑前 \(i\) 个铲屎官接走前 \(j\) 只小猫的最小代价。则 \(f_{i, j} = \min(f_{i, j}, f_{i - 1, k} + a_j \times (j - k) - (s_j - s_k))\)

划分成 \(p\) 段的最小代价 —— 想到 WQS 二分相关的优化技巧。

不过这题没必要 WQS 二分,简单地套个斜率优化就可以了。

斜率优化推式子部分:

\(f_{i - 1, k} + s_k = a_{j}k + f_{i, j} + s_{j} - ja_{j}\)

\(y = f_{i - 1, k} + s_{k}, slope = a_j, x = k, b = f_{i, j} + s_{j} - ja_j\)

斜率单增,求 \(b\) 的最小值,维护一个下凸包即可。时间复杂度 \(O(pm)\)

P4056 [JSOI2009] 火星藏宝图

可以把直接跳分解成先向下走再向右走,则从同一列的若干点直接转移到后面的点 \(x\),一定选取这一列能转移到 \(x\) 的最下方的点进行转移(从收益和代价分别考虑)。这个可以 \(O(m^2)\) 预处理。

将所有点按列为第一关键字,行为第二关键字排序,枚举每个点以及从哪一列转移过来,可以得到 \(O(nm)\) 的做法。

推式子,发现是可以斜率优化的形式。稍微分析一下可以发现之前的枚举顺序不好优化,因为每列的最大行时刻都在变化。

换一下顺序,按行为第一关键字,列为第二关键字进行更新,记 \(f_{i, j}\) 表示到第 \(i\) 行第 \(j\)​ 列的最大权值。

\(f_{i, j} = \min(f_{i, j}, f_{pos_{x}, x} - (i - pos_x)^2 - (j - x)^2 + w_{i, j})\)。其中 \(pos_x\) 表示第 \(x\) 列能转移当前点的最大行,这个可以 \(O(1)\) 实时更新,且支持每一行开一个单调队列进行斜率优化。

斜率优化推式子部分:

\(f_{pos_x, x} - (i - pos_x)^2 - x^2 = -2jx + f_{i, j} + j^2 - w_{i, j}\)

\(y = f_{pos_x, x} - (i - pos_x)^2 - x^2, slope = -2j, x = x, b = f_{i, j} + j^2 - w_{i, j}\)

斜率单减,求 \(b\) 的最大值,维护一个上凸包即可。时间复杂度 \(O(m^2)\)

由于当前点可以由该列上方转移过来,因此实现时要先把当前位置插进队列再进行后续操作。

P2569 [SCOI2010] 股票交易

因为 \(AP_i \ge BP_i\),所以一天内要么买要么卖。

\(f_{i, j}\) 表示第 \(i\) 天持有 \(j\) 支股票的最大收益。

  • 啥也不做:\(f_{i, j} = f_{i - 1, j}\)

  • 第一次买:\(f_{i, j} = -j\times AP_i\)

  • \(K\) 天买:\(f_{i, j} = \max(f_{i - K - 1, k} - (j - k)\times AP_i) (j - k \le AS_i)\)

  • \(K\) 天卖:\(f_{i, j} = \max(f_{i - K - 1, k} + (k - j) \times BP_i)(k - j \le BS_i)\)

能直接用 \(f_{i - K - 1}\) 更新 \(f_i\) 的原因是因为 \(f_{x}\) 相较于 \(f_{x - 1}\) 一定不劣(因为可以啥也不做)

直接枚举 \(i, j, k\)\(O(n^3)\) 的,但可以从小到大枚举 \(j\),滑动窗口维护 \(j - k \le AP_i\)\(f_{i - K - 1, k} + k \times AP_i\) 的最大值,对于卖的情况类似处理,从大到小枚举即可。

P2317 [HNOI2005] 星际贸易

做一遍背包,求出最大贸易额。题目保证了只有一种获得最大贸易额的方法,因此可以通过倒推 dp 数组确定必经星球。

然后求第二问。燃料数的有效范围是 \(2n\),因此可以把 \(R\) 砍下来。

\(f_{i, x}\) 表示在第 \(i\) 个星球停靠并进行加燃料和维护后,飞船上燃料数为 \(x\) 的最小花费。

\(f_{i, x} = \min(f_{j, y} + (x - y + 2)\times P_i + F_i), L_{i} - L_j \le L_0, 2\le y \le x + 2\)

滚动优化:\(f_{i, x} = \min(f_{i, x - 1} + P_i, f_{j, x + 2} + F_i)\),省去了枚举之前油量的步骤。

对每一个 \(x\) 开一个单调队列,维护 \(L_i - L_j \le L_0\)\(f_{j, x + 2}\) 的最大值。

注意当枚举到必经星球时,需要把队列清空,只保留当前星球。

P2515 [HAOI2010] 软件安装

\(i\)\(D_i\) 连边,每个连通块都是一棵基环树,直接用 tarjan 缩一遍点就转成了森林,且其中的每一棵有向树都是根向树。

选一些点获得权值,同时消耗容量,如果一个点被选,则它的父亲也要被选。

做树上背包即可。

由于一些奇怪的原因树上背包挂了一个晚上,并且现在还不知道怎么回事。

P4190 [CTSC2010] 三国围棋擂台赛

状压,记忆化搜索。记 \(f[S0][S1][S2][a][b][x]\) 表示三国分别还剩哪些人、\(a\) 作为上一场胜方与 \(b\) 比赛、\(x\) 为上一场胜者的概率。

P5798 [SEERC2019] Level Up

P4290 [HAOI2008] 玩具取名

简单区间 dp,随便做。

P4099 [HEOI2013] SAO

相关:[CTS2019] 氪金手游[ARC130D] Zigzag Tree

给定一棵树及每条边的相对大小关系,求排名分配的合法方案数。排名 dp,这个是不是被玩烂了啊:|

假定以 \(1\) 为根做树形 dp。设 \(f_{u, i}\) 表示考虑 \(u\) 子树内,\(u\) 节点的排名为 \(i\) 的方案数。

\[\begin{aligned} rk_u > rk_v (u \to v): tmp_{i + j} \leftarrow \binom{i - 1 + j}{i - 1}\times \binom{sz_u - i + sz_v - j}{sz_u - i} \times f_{u, i} \times \sum\limits_{x = 1}^{j}f_{v, x} \\ rk_u < rk_v (v \to u): tmp_{i + j} \leftarrow \binom{i - 1 + j}{i - 1}\times \binom{sz_u - i + sz_v - j}{sz_u - i} \times f_{u, i} \times \sum\limits_{x = j + 1}^{sz_v}f_{v, x} \end{aligned} \]

其中 \(sz_u\) 为未纳入 \(v\) 子树之前 \(u\) 子树的大小。可以采用前缀和优化。该 dp 转移本质上是树上背包,因此时间复杂度为 \(O(n^2)\)

P2507 [SCOI2008] 配对

大概是这个题单里最厉害的一道题。这个题厉害的地方在于贪心而不是 dp。

若没有配对的数不能相同的限制,那么可以将 \(a, b\) 排序,直接对应位置配对即可。

对于上述贪心的证明,考虑构建这样一个模型:左侧 \(n\) 个点,表示 \(a\);右侧 \(n\) 个点,表示 \(b\)

将左右侧的点对连线,两两配对,当如上方案配对时,线段间没有交点;若将两条线段的一侧端点进行交换,即使得两条线段相交,则交换后一定不优。

类似地考虑有限制的情况,即一个位置不能直接配对了,必须要与其它线段交换端点。这种情况下,一定是与越近的线段相交更优,并且相交的线段越小越优。

注意 \(a, b\) 序列内部的数互不相同,因此在最优配对的贪心考虑下,最多存在三个线段相交的情况。

然后就可以对于 \(5\) 种配对情况分讨 dp(\(1\) 种单线段,\(1\) 种两线段相交,\(3\) 种三线段相交),时间复杂度 \(O(n)\)

注意 \(n = 1, a_1 = b_1\) 时判无解。

P3204 [HNOI2010] 公交线路

nmd,\([1, k]\) 号站中,位置 \(i\) 只能是第 \(i\) 个公交车,但 \([n - k + 1, n]\) 号站中,只需包含所有 \(k\) 个公交车即可。

我不会公交车。

\(k \le 8, p\le 10\),猜测状压。但是这个 \(n\) 又大得离谱,可能是爆算组合数,或者是矩阵快速幂优化 dp。

为方便叙述,称一个公交车为一种颜色,相当于在一个长为 \(n\) 的序列上染色,求合法方案数。

一个比较显然的事情是,连续 \(p\) 个位置内必须包含所有颜色。

设计状态 \(f_{i, S}\) 表示填完前 \(i\) 个位置,最后 \(p\) 个位置的状态为 \(S\) 的方案数。

问题就在于这个状态如何设计更合理。我的想法是,状压存储每种颜色最后一次出现的位置。向右转移时,状态也随之左移。如果当前最高位上不为 \(1\),则在所有 \(1\) 位中选择一个删掉,并左移后在最低位填 \(1\);否则直接在左移后的最低位填 \(1\)

由于合法状态只有 \(\binom{p}{k}\) 个,因此可以预处理处状态间的转移关系,用矩阵快速幂优化。

P2501 [HAOI2006] 数字序列

经典套路:\(a_i \to a_i - i\),将严格单增转成单调不降序列。

第一问就是最长不降子序列长度。

对于第二问,继承第一问的 dp 数组 \(f_i\) 表示以 \(i\) 结尾的最长不降子序列长度。

又记 \(g_i\) 表示将 \(1\sim i\) 修改为单调不降所需的最小代价,\(g_i\)\(f_j = f_i - 1\)\(g_j\) 转移过来。

有一个结论是,将 \(j + 1 \sim i - 1\) 全部赋成 \(a_j\)\(a_i\),最终一定能得到最优结果。

最劣 \(O(n^3)\)。离谱而神秘。

P2466 [SDOI2008] Sue 的小球

在最优策略下,由于越早拿走越好,因此如果经过一段区间,区间内的所有小毬一定都会被拿走,所以记录 \(f_{l, r}\) 表示拿走 \([l, r]\)(按横坐标从小到大排序后的编号)内的小毬后得到的最大代价。

关于区间 dp,有下面几件事情:

  • 取完一个区间后,一定停在区间的左右端点处,转移需对这两种情况分别考虑。
  • 如果对每次拿走的小毬的代价分别考虑,则需要知道当前经过了多长时间,而这是不好处理的。不妨考察所有小毬的代价和,可以发现在一段时间内,所有未被取走的小毬的代价减少量是可以快速算出来的。也就是说,dp 时既考虑已取完的小毬的代价,同时也要考虑未被取走的小毬目前减少的代价。思想是 整体思想贡献提前计算

P4728 [HNOI2009] 双递增序列

之前做过。但这题确实很有意思,核心思想是通过 dp 状态将两个序列的信息联系在一起同步更新。

\(f_{i, j}\) 枚举前 \(i\) 个元素,有一个子序列的末尾是 \(a_i\),且该子序列长为 \(j\) 时,另一个子序列末尾的最小值。

\(a_i < a_{i + 1}\)\(f_{i + 1, j + 1} = \min(f_{i + 1, j + 1}, f_{i, j})\)

\(f_{i, j} < a_{i + 1}\)\(f_{i + 1, i - j + 1} = \min(f_{i + 1, i- j + 1}, a_i)\)

P4460 [CQOI2018] 解锁屏幕

\(n < 20\),考虑状压。记 \(f_{S, i}\) 表示已经使用过的点集为 \(S\),最后一步停在点 \(i\) 的方案数。

枚举下一步走哪个点 \(j\),要求 \(i \to j\) 不能穿过未使用过的点。

预处理出 \(C_{i, j}\) 表示从 \(i \to j\) 穿过的点集,则 \(S\) 的补集与 \(C_{i, j}\) 必须无交。

预处理 \(C_{i, j}\)\(O(n^3)\) 的,求答案是 \(O(n^{2}2^{n})\) 的。

P2462 [SDOI2007] 游戏

容易发现字符串 \(S \to T\) 的转移一定满足 \(sort(S)\)\(sort(T)\) 去掉一位字符后形成的字符串,其中 \(sort(x)\) 表示将字符串 \(x\) 排序。然后就随便做了。

P3084 [USACO13OPEN] Photo G

P4495 [HAOI2018] 奇怪的背包

首先要发现一个体积 \(a\) 的最小表示:\(\gcd(a, P)\)。即,能用 \(k\times \gcd(a, P)\) 表示出所有 \(a\) 能表示的数。同理,如果选择了一个数集,那么最小表示应为整个数集的 \(\gcd\) 再与 \(P\)\(\gcd\) 后的结果。

于是本质不同的体积只有 \(d(P)\) 种(\(d(P)\) 表示 \(P\) 的因数个数),记 \(p_i\) 表示 \(P\) 的第 \(i\) 种因数,\(cnt_i\) 表示体积最小表示为第 \(i\) 种因数的个数。

设计 dp:记 \(f_{i, j}\) 表示考虑到第 \(i\) 个因数,\(\gcd(A, P) = p_j\)\(A\) 表示选的因数的集合)的方案数。

\[\begin{aligned} f_{i, j} &\leftarrow f_{i - 1, j} \\ f_{i, \gcd(p_j, p_i)} &\leftarrow f_{i - 1, j} \times (2^{cnt_i} - 1) \end{aligned} \]

注意 \(f_{pcnt, i}\) 求出来的是最小表示恰好为 \(p_i\) 的方案数,还要求对因数求一遍前缀和,因为小的因数也可能表示出大的因数。

时间复杂度 \(O(n + Q + d(P)^2)\)。最难的地方在于看出最小表示,如果没看到一个叫 "关于约数个数上界" 的贴子我还做不出来。

P2473 [SCOI2008] 奖励关

很明显的状压。记 \(f_{i, S}\) 表示进行了 \(i\) 轮,已吃集合为 \(S\) 时的最大期望值。

转移时枚举进行完第 \(i\) 轮后的集合 \(S\),对每种宝物分别累计合法的贡献最大值。

写了发现这玩意儿最后很难把所有状态合起来求期望,因为到达不同状态的权重是不一样。就算可以求出权重,精度缺失也会很严重。

所以去看题解了。所以求期望的题还是要多去想 逆推 做法。

重新定义 \(f_{i, S}\) 表示前 \(i - 1\) 已吃集合为 \(S\)\(i \sim k\) 轮的的最大期望权值。

\[\begin{aligned} f_{i, S} = \frac{1}{n}\sum\limits_{j = 0}^{n - 1}\max(f_{i + 1, S}, [valid]f_{i + 1, S | (1 << j)} + p_i) \end{aligned} \]

答案为 \(f_{1, 0}\)

P3888 [GDOI2014] 拯救莫莉斯

要求每个格子要么被标记要么周围(四连通)至少有一个格子被标记。\(n \times m \le 25\) 显然是给 \(2^{25}\) 做的。

出题人温馨地给了 \(m \le n\) 的条件,于是很快可以反应过来 \(m \le \sqrt{50} = 7\)

于是可以状压上两行,枚举当前行。具体地,记 \(f_{i, S1, S2}\) 表示当前行为 \(i\),第 \(i\) 行状态为 \(S1\),第 \(i - 1\) 行状态为 \(S2\)\(1 \sim i - 1\) 行均合法的最小代价。

暴力转移即可,这部分不想写 markdown 了。

我实现的时间复杂度是 \(O(nm2^{3m})\),有点高贵。

P6239 [JXOI2012] 奇怪的道路

在一个数轴上看这个问题,对于每个右端点,向左侧一定范围内的点进行连边。

由于要满足奇偶限制,且 \(k \le 8\),于是可以状压当前位置及之前 \(k\) 个位置的奇偶情况。

\(f_{i, j, S}\) 表示考虑编号为 \(1 \sim i\) 的点之间的连边,共连了 \(j\) 条边,状态为 \(S\) 的方案数。

这个是好转移的,我也不写 markdown 了。需要注意的是要先枚举连到哪个点,再枚举 \(f_{i, j}\) 中的 \(j\),否则会计重。

我实现的时间复杂度为 \(O(nmk2^k)\)

P3991 [BJOI2017] 喷式水战改

P4574 [CQOI2013] 二进制A+B

原来是数位 dp,那我肯定做不出来。太差劲!加训数位DP!

\(f(i, x, y, z, 0/1)\) 表示考虑到从低到高的第 \(i\) 位,共用 \(x\)\(a\)\(1\)\(y\)\(b\)\(1\),确定了 \(z\)\(c\)\(1\),并且 \(i\)\(i + 1\) 位是否进位。

转移枚举 \(x, y, z, 0/1\)\(a\) 的第 \(i\) 位填什么,\(b\) 的第 \(i\) 位填什么,\(c\) 的第 \(i\) 位填什么,并判断转移是否合法。暴力转移即可。

P7914 [CSP-S 2021] 括号序列

区间 dp 好题。

好题就是好题,我不得不承认,时隔两年,我仍然会被它卡住。

实际上,现在能困扰我的唯一问题就是,形如 (...)**(...)**(...)(...) 这样的序列如何避免计重。((...) 均为合法序列)

但仔细想想又会发现还算简单,我需要对 (...)** 形式的序列和所有情况下的合法序列分别计数,并在上面那种情况钦定第一个 (...)** 的位置,用左侧 (...)** 形式的序列数与右侧所有可能的合法序列数相乘即可避免计重。

由于对 (...)** 计数时发现还会计重,于是又维护了 (...) 形式合法序列的数量。

关键点在于计数时 钦定开头 的思想。

自己做出来了!很开心!会区间 dp 了!很开心!

P7961 [NOIP2021] 数列

\(f_{i, w, j, k}\) 表示考虑 \(2^{0} \sim 2^{i}\),填了 \(w\) 个数,向 \(i + 1\) 位进位了 \(j\)\(1\),前 \(i\) 位共 \(k\)\(1\) 的方案数。

\[\begin{aligned} f_{i, w + x, x + j / 2, k + (x + j / 2)\& 1} \leftarrow a_i^{x} \times \binom{n - w}{x} f_{i - 1, w, j, k} \end{aligned} \]

最后还要再用个类似的 dp 转移稍微处理一下,把没有进位完的 \(1\) 给传到高位去。

自己做出来了!很开心!会数位 dp 了!很开心!

P5664 [CSP-S2019] Emiya 家今天的饭

以下记 \(s_i = \sum\limits_{j}a_{i, j}\)\(a_{i, j}\) 即为原题面的意义。

这个也很典,印象最深刻的就是从这里学到了设计状态时 记录差值 的技巧。但是居然不会 正难则反 了!很差劲!

正着莽不会做,考虑用没有 \(\lfloor \frac{k}{2} \rfloor\) 限制时的合法总方案数 \(\prod\limits_{i = 1}^{n}(s_i + 1) - 1\) 减去其中违反 \(\lfloor \frac{k}{2} \rfloor\) 限制的方案数。

这样算的好处就在于,当一种食材的出现次数超过一半时,我们可以确定该食材是什么,于是可以只记录这种食材的数量和总共做了多少道菜,而不用知道其它食材具体出现了多少次。

枚举当前钦定食材 \(u\) 出现次数超过一半,记 \(f_{i, j, k}\) 表示考虑前 \(i\) 种烹饪方法,食材 \(u\) 用了 \(j\) 次,总共做了 \(k\) 道菜的方案数。状态转移可以做到 \(O(1)\)

但时间仍然不可观。枚举 \(u\) 有一个 \(O(m)\),枚举烹饪方法有一个 \(O(n)\),枚举 \(j\) 有一个 \(O(n)\),枚举 \(k\) 有一个 \(O(n)\),总时间复杂度为 \(O(mn^3)\),数量级为 \(2 \times 10^9\)

这时就要祭出记录差值了!由于我们最终统计结果时要比较 \(u\) 与其它食材的数量,我们可以将 \(j, k\) 转成记录 \(u\) 与其它食材的数量的差值。

记录差值的可行性在于:

  • 原 dp 转移时未用到 \(j, k\) 作为系数。
  • 最终统计答案时,可以利用差值代替 \(j, k\)

重新设计状态 \(f_{i, d}\) 表示考虑前 \(i\) 种烹饪方法,\(cnt_u - cnt_{others} = d\) 的方案数。转移枚举是否用当前烹饪方法做菜、是否是用 \(u\) 做菜,简单转移即可:

\[\begin{aligned} f_{i, d} &\leftarrow f_{i - 1, d} \\ f_{i, d + 1} &\leftarrow a_{i, u}\times f_{i - 1, d} \\ f_{i, d - 1} &\leftarrow (s_i - a_{i, u}) \times f_{i - 1, d} \end{aligned} \]

最后统计 \(d > 0\)\(f\) 即可,时间复杂度降为 \(O(mn^2)\)

自己(?)做出来了(吗?),不是很开心。

P1850 [NOIP2016 提高组] 换教室

不要试图怀疑期望线性性的正确性。

以下记 \(w(x, y)\) 表示 \(x, y\) 之间的最短路,\(p_i = u_{i, 0 / 1}\) 表示在时间 \(i\) 处于原/新教室,\(W\) 表示路径总和。

\[\begin{aligned} E[W] = E[\sum\limits_{i = 1}^{n - 1}w(p_i, p_{i + 1})] = \sum\limits_{i = 1}^{n - 1}E[w(p_i, p_{i + 1})] \end{aligned} \]

其中 \(E[w(p_i, p_{i + 1})]\)\(p_i, p_{i + 1}\) 的概率乘积决定。这无论怎样从直观上看来都是一个荒诞的结论,但如果按期望的原始定义展开,会发现与这条边无关的项会被抵消掉,最后得到与这个结论一致的结果!

\(f_{i, j, 0/1}\) 表示考虑前 \(i\) 个时间,申请了 \(j\) 次,当前是否申请的期望最小值。

\[\begin{aligned} f_{i, j, 0} &\xleftarrow{\min} f_{i - 1, j, 0} + w(u_{i - 1, 0}, u_{i, 0}) \\ f_{i, j, 0} &\xleftarrow{\min} f_{i - 1, j, 1} + k_{i - 1}w(u_{i - 1, 1}, u_{i, 0}) + (1 - k_{i - 1})w(u_{i - 1, 0}, u_{i, 0}) \\ f_{i, j + 1, 1} &\xleftarrow{\min} f_{i - 1, j, 0} + k_{i}w(u_{i - 1, 0}, u_{i, 1}) + (1 - k_i)w(u_{i - 1, 0}, u_{i, 0}) \\ f_{i, j + 1, 1} &\xleftarrow{\min} f_{i - 1, j, 1} + k_{i - 1}k_iw(u_{i - 1, 1}, u_{i, 1}) + (1 - k_{i - 1})k_iw(u_{i - 1, 0}, u_{i, 1}) + k_{i - 1}(1 - k_i)w(u_{i - 1, 1}, u_{i, 0}) + (1 - k_{i - 1})(1 - k_i)w(u_{i - 1, 0}, u_{i, 0}) \end{aligned} \]

dp 是小事情。

不会概率论,so sad.

P6748 『MdOI R3』Fallen Lord

换个说法:一个节点 \(u\) 的周围至少有 \(\lfloor \frac{d_u}{2} \rfloor + 1\) 条边的权值 \(\le a_u\),其中 \(d_u\)\(u\) 的度数。

另外可以发现,若想让边权和最大化,一条边 \((u, v)\)取值是很有限的,只可能为 \(a_u, a_v, m\) 中的一个。

于是可以尝试设计 dp 状态:\(f_{u, 0 / 1/ 2}\) 表示分别表示 \((u, fa_u)\) 边权取 \(a_u, a_{fa_u}, m\) 时,使得 \(u\) 子树内不会有人造反的最大边权和(包含 \(u\) 连向父亲的边)。

dp 转移就很有意思了:我们应当把当前节点的所有子节点的 dp 值拉出来,整体观察

对于第 \(i\) 个子节点 \(v\),分为 \(\le a_u\) 的 dp 值和 \(> a_u\) 的 dp 值,对于每种情况,取满足条件的最大的 dp 值,分别记为 \(A_i, B_i\)。如果没有满足条件的 dp 值,记为负无穷。

于是我们需要对于 \(m\) 个子节点,在 \(\forall i, 1 \le i \le m\) 中选出 \(A_i\)\(B_i\),使得选出数的权值和最大,并至少从 \(A\) 中选出 \(\lfloor \frac{d_u}{2} \rfloor(+1)\)\(+1\) 是要考虑 \((u, fa_u)\) 的边权填什么)。

这个问题被 \(\color{black}{\text{l}}\color{red}{\text{iuhangxin}}\) 秒了。考虑 调整法,先全部选 \(B_i\),然后转成至少选 \(\lfloor \frac{d_u}{2} \rfloor(+1)\)\(A_i - B_i\)。从大到小选差值即可。

为了避免爆 long long,考虑 \(B_i \xleftarrow{\max} A_i\),转成恰好选 \(\lfloor \frac{d_u}{2} \rfloor(+1)\)\(A_i - B_i\)

是一道有趣的 dp 好题!

posted @ 2023-08-12 14:36  Schucking_Sattin  阅读(28)  评论(0)    收藏  举报