2024.1.12 fxj(原 zjk)DP 专题

2024.1.12 fxj(原 zjk)DP 专题

GYM102904B Dispatch Money

题意

长度为 \(n\) 的排列,将其分段,每段的代价为逆序对数加 \(k\),求最小代价和。

\(n \le 3 \times 10^5\)

分析

逆序对数是很经典的有决策单调性的区间权值,考虑分治优化 dp。

由于是在线转移,考虑使用 CDQ 解决,如果用莫队维护逆序对数,根据整体二分经典结论:指针移动次数 \(\mathcal O(n\log^2 n)\)

用 BIT 维护,总复杂度 \(\mathcal O(n\log^3 n)\),可以通过。

Code

提交记录:https://codeforces.com/gym/102904/submission/241255308

GYM102331J Jiry Matchings

题意

给定 \(n\) 个点的带边权树,对 \(k = 1 \sim n - 1\),求大小为 \(k\) 的最大匹配。

\(n \le 2 \times 10^5\)

分析

考虑朴素 dp,设 \(f_{u, i, 0/1}\) 表示 \(u\) 为根的子树,匹配了 \(i\) 组,是/否匹配了 \(u\) 的最大权值。

由于二分图最大权匹配显然是费用流可解问题,所以该 dp 具有凸性,可以 \(\mathcal O(sz)\) 的合并两个背包,这启示我们可以类全局平衡二叉树分支合并,可以做到复杂度 \(\mathcal O(n\log n)\)

实现不精细的通过树剖优化的 dp 可以做到 \(\mathcal O(n\log^2 n)\),也可以通过,给出该实现。

Code

提交记录:https://codeforces.com/gym/102331/submission/241414033

HDU6094 Rikka with K-Match

题意

\(n \times m\) 的带边权网格图,求大小为 \(k\) 的最小权匹配权值。

\(n \le 5 \times 10^4, m \le 4\)

分析

朴素 dp 设 \(f_{i, j, s}\) 表示考虑到第 \(i\) 行,匹配了 \(j\) 条边,上一行匹配的状态为 \(s\) 的最小权值。

该问题显然具有凸性,考虑使用 wqs 二分优化朴素 dp,注意转移顺序。

时间复杂度 \(\mathcal O(nm2^m\log v)\)

Code

提交记录:https://paste.ubuntu.com/p/qk9qzSS6F4/http://www.gdfzoj.com:23380/submission/369741

GYM102268J Jealous Split

题意

给一个长度为 \(n\) 的非负整数序列 \(a\),你需要将其划分成 \(k\) 段。定义第 \(i\) 段的和为 \(s_i\),最大值为 \(m_i\),你的划分方案需要满足 \(\forall i \in \{1, 2, \dots, n\}, |s_i − s_{i+1}| \leq max(m_i, m_{i+1})\)

构造一个方案或输出无解。

\(3 \leq k \leq n \leq 100\,000\), \(0 \leq a_i \leq 50\,000\)

分析

如果出现非法状态,显然可以将和大的一边分一点向小的一边,这下我们可以确定对于最有分组方式有 \(s_i^k + s_{i + 1}^k\) 取到最小值,取 \(k = 2\),可以通过 wqs 二分求解。

但是注意到 wqs 二分不能精准控制段数,只能找出上下界,这个时候要在保证满足四边形不等式约束的前提下在相邻位置调整,即找到一个 \(p_i < q_j \land q_{j + 1} < p_{i + 1}\) 的决策点。

复杂度 \(\mathcal O(n \log v)\)

Code

提交记录:https://codeforces.com/gym/102268/submission/241522520

[CTS2021] 数组

题解

求在满足 \(a_i \times a_{i + 1} \ge b_i\) 的前提下 \(\sum a_i\) 的最小值,注意 \(a_i \in \mathbb{R}^*\)

\(n \le 3000, b_i \le 4000\)

分析

考虑全程乘积对 \(b_i\) 要么取等,要么大于(且不连续),不然就太亏了,显然可以通过调整变更小。

那么对于一段取等的连续段,设左端点为 \(v\),那么最后的和一定形如 \(pv + \dfrac{q}{v}\),拿最小值和两端点处的值就都知道了。

现在考虑连接处,你既然都大于了,那两边不去到最优就太亏了,所以就能 dp 了,设 \(f_{i, j}\) 表示最后一段填的是 \([i, j]\) 的最小和,显然这是离线 dp 问题,可以通过前缀 \(\min\) 加二分最优决策点做到 \(\mathcal O(n^2\log n)\)

Code

提交记录:https://paste.ubuntu.com/p/XySGc73Z9R/http://www.gdfzoj.com:23380/submission/369947

「ZJOI2019」麻将

题解

一副麻将是胡的当且仅当达成以下两个条件之一:

  • 存在一个对子,三个面子;
  • 存在不相同的七个对子。

\(n\) 种牌,每种 \(4\) 张,给定前 \(13\) 张,求胡牌需要的期望轮数。

\(n \le 100\)

分析

考虑将一个状态转换成每种花色 \(i\) 抽到了 \(a_i\) 张,那么如何对它 dp 检测是否胡牌呢?我们设 \(f_{i, j, k}\):考虑到 \(i\),钦定有 \(j\)\((i - 1, i)\),有 \(k\)\(i\) 的最多面子数。为了以防形成考虑之外的面子,\(j, k < 3\)

显然转移与 \(i\) 无关,考虑将转移的 DFA 建出来,进行 dp 套 dp,设 \(f_{i, j, k}\):前 \(i\) 中花色,走到节点 \(j\),用了 \(k\) 张牌的方案数。由于状态数 \(m = 2092\) 很小,所以暴力转移即可。

最后统计答案在非胡牌节点统计每种概率之和即可。

复杂度 \(\mathcal O(n^2m)\)

Code

提交记录:https://loj.ac/s/1977794

CF1456E XOR-ranges

题意

有序列 \(\{a_n\}\)\(a_i\)\([l_i, r_i]\) 中自由选取,\(r_i < 2^k\),给定每个二进制位的代价 \(c_i\),求 \(\sum \operatorname{cost}(a_i \bigoplus a_{i - 1})\) 的最小值。

\(n \le 50, k \le 50, c_i \le 10^{12}\)

分析

显然可以将贡献拆到每一位算,考虑数位 dp,观察当限制被打破时可能出现的现象。

考虑第 \(i\) 位,对于序列 \(\{a_n\}\),若 \(a_{2 \sim n - 1}\) 此时已不受限制,则这一位的贡献 \(\operatorname{cost}(a) = \operatorname{cost}(a_1 \bigoplus a_n)\)(显然可以令 \(\forall 1 < i < n, a_i = a_1\))。设 \(h_i\)\(a_i\) 打破限制的二进制位(从低到高),这说明:从高到底考虑(当前到 \(i\)),\(h_j \le i\) 的位置将会把一整段分为若干小区间,而第 \(i\) 位的贡献之和这些位置有关。

在上面限制的前提下就可以考虑区间 dp,设 \(f_{i, l, r, 0/1, 0/1, 0/1, 0/1}\) 表示考虑到二进制位 \(i\),目前解决的是 \([l, r]\) 这个子问题,钦定 \(h_{l - 1}, h_{r + 1} \le i\),且 \(a_{l - 1} / a_{r + 1}\) 顶上/下界,第 \(i\) 位是/否要取反(取反说明 \(h_j = i\))。

转移分两部分:

  • 不存在分界点:\(i \gets i - 1\)

  • 存在分界点:枚举分界点 \(l \le j \le r\)\((l, r) \gets (l, j - 1) + (j + 1, r)\),具体的还要枚举 \(h_j\) 是否等于 \(i\)

复杂度 \(\mathcal O(n^3k)\)

Code

提交记录:https://codeforces.com/contest/1456/submission/241557855

HDU5121 Just A Mistake

题意

给定一颗 \(n\) 个点的树,对于所有 \(1 \sim n\) 的排列,依次加入 \(p_i\) 并维护独立集,求独立集大小的和模 \(10^9 + 7\) 的值。

\(n \le 200\)

分析

考虑设 \(f_{u, i}\) 表示已 \(u\) 为根,\(u\) 在子树中排名为 \(i\)\(u\) 必选的方案数。

考虑枚举儿子 \(v\),要求 \(v\) 必须在 \(u\) 之后被选,组合数计算法案即可。

Code

提交记录:https://paste.ubuntu.com/p/658pr2gdRf/http://www.gdfzoj.com:23380/submission/369887

TopCoder 11779 Pikachu

题意

存在三种字符,它们的代价分别是 \(\{2, 2, 3\}\),用它们拼出 \(n\) 个字符串,且 \(\not \exist i, j, s_i \text{ is preffix of } s_j\),最小化 \(\sum a_i c_i\),其中 \(c_i\) 位选用的字符的代价之和,\(a_i\) 由输入给定,并求出方案数模 \(10^9 + 7\)

\(n \le 30\)

分析

考虑用这三种字符建出一个特殊的字典树,定义一个节点的层数为 \(c_i\)

显然每一层的节点要么形成我选用的字符串,要么向下延展,所以只需要接下来三层的点数就可以表示当前的状态。

所以考虑 \(f_{i, a, b, c}\) 表示已经使用 \(i\) 个节点,当前层,下一层,下下层的节点数为 \(a, b, c\)

注意计算贡献可以考虑有多少个点将跨过当前这一层,即枚举这一层放 \(j\) 个点,贡献为 \(n - i - j\)

复杂度 \(\mathcal O(n^5)\)

Code

提交记录:https://paste.ubuntu.com/p/RVhxGjHrYn/http://www.gdfzoj.com:23380/submission/370377

GYM102155B Short Random Problem

题意

给你一棵由 \(n\) 个顶点组成的树,每条边的长度是一个实数,在 \(0\)\(1\) 之间独立均匀地随机选择,求这棵树的直径的期望值。

\(n \le 100\)

分析

先简化问题,如果枚举直径中点在那一条边 \((u, v, w)\) 上(不妨假设 \(d_u < d_v\)),则需满足 \(d_v < \dfrac{d_u + d_v + w}{2} < d_u + w\),就是 \(d_v < d_u + w\),这样的话就具体化到了两边的最大深度。

考虑概率累计函数 \(F(x) = P(D \le x)\),表示当前树的最大深度,那么在此基础上加一条边(相当于从儿子转移至父亲)就有 \(G(x) = \displaystyle\int_0^1 F(x - t)dt\)

考虑这个函数的性质:

  • 对于任意树的形态,\(F(x)\) 是一个分段的有限多项式(产生性的段的原因是 \(x - t\) 属于上一段或不存在);
  • \(F^\prime(x)\)\(P(x = D)\) 的概率密度;
  • \(\displaystyle\int_{-\infty}^{\infty}(1 - F(x))dx = E(D)\)

\(F(x) = f_i(x - (i - 1)) \ (i - 1 \le x \le i)\),考虑怎么计算转移:转移相当于 \([x - 1, x]\) 这一部分的面积,但是有一部分在前一段,考虑容斥,变成总面积减 \([i - 2, x - 1]\) 的部分。具体的 \(g_i(x) = \displaystyle{\int (f_i(x) - f_{i - 1}(x))dx + \int_0^1f_{i - 1}(x)dx}\)

最后统计答案的时候可以分成 \(E(d_u)\) 在减去 \(d_u + w < d_v\)\(d_u\) 的期望,右侧 \(E(d_v)\) 同样计算,具体的:

\[\displaystyle{\frac{1}{2} + E(d_u) + E(d_v) - \int_{-\infty}^\infty xP(d_u + w = x)(1 - P(d_v \le x))dx + E(d_v) - \int_{-\infty}^\infty xP(d_v = x)P(d_u + w \le x)dx} \]

复杂度 \(\mathcal O(n^4)\)

Code

提交记录:https://codeforces.com/gym/102155/submission/241864849

P8497 [NOI2022] 移除石子

题意

\(n\) 堆石子,第 \(i\) 堆有 \(a_i\) 枚,通过如下操作将所有石子移除:

  • 选择 \(i\),一处至少 \(2\) 枚石子;
  • 选择区间 \([l, r]\),满足区间长度至少为 \(3\),令 \(\forall i \in [l, r], a_i \gets a_i - 1\)

给定 \(n, \{l_n\}, \{r_n\}\),求有多少中不同的满足 \(a_i \in [l_i, r_i]\)\(\{a_n\}\),在任意加入恰好 \(m\) 个石子后能被完全移除,答案对 \(10^9 + 7\) 取模。

\(T \le 10, n \le 1000, r_i \le 10^9, m \le 100\)

分析

考虑如何判断一个 \(\{a_n\}\) 能否被移除。

简化题意,先假设 \(k = 0\):设计 \(f_{i, j, k}\) 表示考虑 \(1 \sim i\),钦定 \(j\) 个二操作至少延伸到 \(i\)\(k\) 个操作至少延伸到 \(i + 1\),是否可行。转移要枚举以这一位为终点和起点的二操作分别有多少个,设有 \(l\) 个以 \(i\) 为起点,则要求 \(a_i - j - k - l \in \{x | x = 0 \lor x \ge 2\}\)。需要优化。

注意到:

  • 不可能出现相同的二操作,否则可以用一操作代替;
  • 操作区间长度只能为 \(\{3, 4, 5\}\) 否则可以分裂为更小的区间的共同效果。

所以:

  • 每个点出发的区间数小于等于 \(3\),即 \(l \le 3\),所以 \(k \le 3\)

  • \(i\) 时长度已达 \(3\) 的区间只有:起点 \(i - 2\) ,长度为 \(3, 4, 5\);起点 \(i - 3\),长度为 \({4, 5}\);起点 \(i - 4\),长度为 \(5\);共 \(6\) 种,即 \(j \le 6\)

进一步的优化发现:同时出现 \(4, 5\) 是可以用一次一操作和 \(3, 4\) 代替,所以 \(j \le 4, k \le 2\)

但是直觉上觉得选择这么多二操作,可能出现大量浪费,不如用一操作代替,经过分类讨论,发现实际上 \(j \le 2, k \le 2\) 即可。

讨论加入 \(k\) 的情况:我们可以通过 dp 算出需要的石子数的下界,所以我们很希望能将恰好弱化为至多

讨论:

  • \(k = 1\),讨论不加入石子时有解的局面:

    • 出现一操作,把该石子在这个操作中一同去掉即可;
    • 有长度大于 \(3\) 的二操作,拆成一次操作去掉端点和额外石子和一次长度减一的二操作;
    • 有二操作且 \(n > 3\),考虑延伸这个二操作。

    综上,只有当不存在操作(全零)或 \(a = \{1, 1, 1\}\) 时会矛盾,特判掉就行。

  • \(k > 1\),分类讨论:

    • \(k = 0\) 时有解,则用一次一操作将额外的全部消除;
    • \(k = 1\) 时无解,不可能由某个局面加入 \(k - 1\) 个石子后由有解变为无解。

综上特判 \(\{0, 0, \dots\}, \{1, 1, 1\}\) 即可完成弱化。

将状态改为最小的额外石子数即可,转移的时候考虑设 \(v = a_i - j - k - l\),那么贡献 \(w = \cases{-v & v < 0 \\ 1 & v = 1 \\ 0 & otherwise}\)。复杂度 \(\mathcal O(n\prod (r_i - l_i + 1))\),代码:https://uoj.ac/submission/673513

\(k = 0\) 的部分还启发我们进行 dp 套 dp,不难发现当 \(a_i > j + k + l\) 时本质相同,也就是说 \(8 \sim \infty\) 可以认为是同一种状态,我们考虑建出 DFA 进行转移,复杂度 \(\mathcal O(nS)\)\(S\) 为状态数,大概级别不超过 \(2^9\)

我们尝试将其搬到 \(k > 0\) 上,\(S\) 的理论上界达到 \(102^9\)\(0 \sim 100\),和无解),但是不难由贡献的形式感受到同一状态的九个值不会相差很大,实际上 \(S = 8765\),可以通过。

复杂度 \(\mathcal O(nS)\)

Code

提交记录:https://uoj.ac/submission/673523

posted @ 2024-01-17 21:14  JWRuixi  阅读(41)  评论(0编辑  收藏  举报