2025 提高刷题 - DP

news/2025/1/24 21:57:48/文章来源:https://www.cnblogs.com/laoshan-plus/p/18690402

2025 提高刷题 - DP

A. CF1970G2 Min-Fund Prison (Medium)

本应是典题,愣是瞪了良久。

显然对于加边这个操作只需用并查集维护连通块,最后加上连通块的个数减一条边即可。所以只需考虑 \(x^2+y^2\) 最小即可。显然,在 \(x+y=n\) 的情况下,\(x,y\) 越接近肯定是越好的。所以我们考虑怎么删边,删边分两种情况,要么删原图上的割边,要么删掉自己加的边。对于割边,因为 \(n\) 很小,所以我们直接暴力枚举每次 ban 掉的边,DFS 找出 ban 掉一条边后两个子图的大小(前提是这条边是割边,才能分成两个子图)。对于加边,显然最后分成的两个子图就是 \(\text{siz}_i\)\(n-\text{siz}_i\),其中 \(\text{siz}_i\) 就是 \(i\) 所在连通块的大小。

然后跑一个可行性背包,转移出其中一个连通块能否通过删割边/删加边使得大小为 \(k\)。转移时只转移每个连通块,分两种情况讨论,要么是删掉加边,此时 \(f_j\gets f_{j-\text{siz}_i}\),要么是删掉割边,此时我们从上一步处理出来的子图大小里转移,从 \(f\)\(g\) 转移即可。

最后只需判断是否存在一个大小使得 \(f_i=1\lor g_i=1\) 即可。

B. CF1917F Construct Tree

首先将 \(l\) 从小到大排序。

  • 性质 1:如果 \(l_n+l_{n-1}>d\),也就是序列中最大的两个值的和大于 \(d\),必定无解;
  • 性质 2:如果存在 \(l\) 的一个子集 \(S\),使得 \(S\) 的和为 \(d\),且 \(S\) 包含 \(l_n\),必定有解;
  • 性质 3:如果存在 \(l\) 的一个划分 \(S_1,S_2\) 使得这两个子集的和都不小于 \(l_n\),且 \(S_1+S_2\) 的和恰好为 \(d\),则一定有解。

性质 1 直接排序判定,性质 2 可以跑一个可行性背包 \(O(nd)\) 判定,性质 3 也可以通过一个背包 \(O(nd^2)\) 判定。加上 \(\tt bitset\) 优化,复杂度做到 \(O(\frac{nd^2}w)\),可以通过。第一个 DP 状态的设计是平凡的,第二个实际上就是多套了一层,令 \(f_{i,j,k}\) 表示枚举到 \(l_i\)\(S_1\) 的大小为 \(j\)\(S_2\) 的大小为 \(k\) 的方案数,第一维显然可以省略,当前的 \(l_i\) 显然要么是分给 \(S_1\),要么是分给 \(S_2\),两种情况都一转移即可。最后的判定当然是 \(\exists i\in[l_n,d-l_n]\) 使得 \(f_{i,d-i}=1\)

可行性背包套 \(\tt bitset\) 的套路算是积累了。不过这题貌似三个性质才是难点罢。

C. CF1914G2 Light Bulbs (Hard Version)

只能说是道治你代码能力的好题,如果你用线段树优化建图 + Tarjan + 拓扑排序的话。

官解的什么异或哈希是肯定不会的,我们考虑思路更为亲民的图论做法。其实这题长得就很像图论,我们把一种颜色向中间区间的所有颜色连边,最后就形成了若干个连通图。给每个连通图跑 Tarjan,就得到若干个 DAG,最后只需统计每个 DAG 的入度为 \(0\) 的点的数量和大小的乘积即可。

时间复杂度瓶颈在于连边,考虑线段树优化建图。虽然只是套个板子上去,但这样做又会带来新的问题,因为线段树优化建图会产生许多不必要的节点,并把整张图连成一个连通图。所以我们不能再判断连通块了,并且在 Tarjan 的时候只能对有用的点计入 \(\text{siz}\)。跑完 Tarjan 后,应该建张新图,然后跑拓扑排序,对入度为 \(0\) 的点打上标记,最后答案就是这些点的数量之和以及 \(\text{siz}\) 的乘积。

最后:但凡涉及线段树优化建图,数组大小一定开 8 倍!

D. CF1906H Twin Friends

DP 是很好看出的,但是设不出来状态啊。

遇到这种看起来很假大空的计数题,一般的想法是简化。比如这题中易得的一点是 \(A\) 的顺序其实无关紧要,所以 \(A\) 可以固定着求,最后乘上 \(A\) 的排列数即可,也就是 \(\dfrac{n!}{\prod\text{cnt}(\texttt a\sim\texttt z)!}\),其中 \(\text{cnt}\) 是某个字母在 \(A\) 中出现的次数。接下来考虑怎么设计状态。

这个状态还是很的,设 \(f_{i,j}\) 表示放置到第 \(i\) 个字母,其中为了匹配第 \(i\) 个字母放置了 \(j\) 个字母 \(i\)下一位字母的方案数。转移方程是

\[f_{i,j}=\binom{\text{cnt}(a_i)}j\times\sum_{k=0}^{\text{cnt}(b_i)-\text{cnt}(a_i)+j}f_{i-1,k} \]

解释一下这个方程,因为有当前字母 \(a_i\) 要用 \(j\) 个下一位字母,所以就要用 \(\text{cnt}(a_i)-j\)这一位字母,所以它的上一位 \(a_{i-1}\) 最多就只能用 \(\text{cnt}(b_i)-\big(\text{cnt}(a_i)-j\big)=\text{cnt}(b_i)-\text{cnt}(a_i)+j\) 个这一位字母。所以把满足条件的 \(f\) 数组求和,再乘上从总共的 \(\text{cnt}(a_i)\) 个字母中挑出 \(j\) 个字母匹配下一位字母的方案数。这就是这个转移方程。

最后的答案显然是 \(f_{26,0}\) 乘上文所说的 \(A\) 的排列数,因为最后一个字母没有下一位字母。

发现很容易能用前缀和优化到 \(O(26n)\)

E. CF1905E One-X

尝试找出每个节点的贡献。易得一个节点 \(x\) 如果有贡献,必定是左右子树都至少选一个,总的方案数为 \((2^{\text{len}(l)}-1)(2^{\text{len}(r)}-1)x\)。暴力地建树统计是 \(O(n)\) 的,但是我们发现 \(\text{len}(l)\)\(\text{len}(r)\) 有很多重复,于是考虑把方案数存储下来,记忆化搜索。因为树高是 \(\log\) 的,而我们每次只会对下一层累加答案,所以可以处理出每一层、每一区间长度有多少个节点,以及总的节点编号和。记为 \(\text{cnt}(x)\)\(\text{val}(x)\),易得:

\[\begin{aligned} \text{cnt}(l)&=\text{cnt}(r)=\text{cnt}(x)\\ \text{val}(l)&=2\times\text{val}(x)\\ \text{val}(r)&=2\times\text{val}(x)+\text{cnt}(l) \end{aligned} \]

手模一下不难得到。

另外,还有一种做法是把每个节点的贡献转化为 \(f(x)=kx+b\),然后递推 \(k\)\(b\) 并计算答案。和之前模拟赛的这个比较类似。

套路:线段树相关的统计,可以去找每个节点的贡献,尝试按层高为 log 的特性和二叉树的特性统计答案。

F. CF1874C Jellyfish and EVA

原,位于提高组数学专题 1。

显然 DP,设 \(f_i\) 为从 \(i\)\(n\) 的概率,那么有

\[f_u=\sum_{v\in\text{son}(u)}f_v\times p_{u\to v} \]

其中 \(p_{u\to v}\) 是从 \(u\)\(v\) 的概率,接下来的任务是计算这个 \(p_{u\to v}\)。但我们发现它特别不好计算,发现从一个节点到另一个节点的概率仅和它的 \(f_v\) 有关,\(f_v\) 越大的点会被优先考虑。所以把 \(p_{u\to v}\) 转化为 \(g_{\text{deg}(u),i}\) 表示 \(v\) 是第 \(i\) 优的节点。考虑计算 \(g_{i,j}\)

\[g_{i,j}=\begin{cases}\dfrac1i&j=1\\[1ex]\dfrac{j-2}i\times g_{i-2,j-2}+\dfrac{i-j}j\times g_{i-2,j-1}&j\ne1\end{cases} \]

首先如果是最优的点肯定考虑优先选它,成功的概率为 \(1/i\)。否则一定就是最优的点没有去成,说明我们选的点不是我们期望的最优点。此时分两种情况,要么是选了比 \(j\) 更优但不是最优点的点,概率为 \((j-2)/i\),此时 \(j\) 点成为总度数 \(-2\) 时排名也靠前两位的点;要么是选了比 \(j\) 更劣的点,也是同理的。

难点全在 \(g\) 数组的预处理上。

G. CF1870E Another MEX Problem

\(\text{XOR}\)\(\text{MEX}\),不好做最优化 DP。但是因为 \(n\le5000\),所以异或出来的最大值不会超过 \(2n\),可以做可行性 DP。设 \(f(i,j)\) 表示考虑到前 \(i\) 位,能否使得答案为 \(j\)。则有转移方程

\[f(i+\mathit{len},j\oplus\operatorname{MEX}(i+1,i+\mathit{len}))\gets f(i,j) \]

暴力转移是 \(O(n^3)\) 的。但是我们发现很多 \(f(i,j)\) 都是 \(0\),不能提供贡献,但我们依然要遍历它,造成了时间的浪费。如果我们能只转移有用的区间,就能降低时间复杂度。

考虑到如果一个区间 \([l,r]\) 的子区间 \([l',r']\) 满足 \([l',r']\subsetneq[l,r]\),但 \(\operatorname{MEX}(l',r')=\operatorname{MEX}(l,r)\),那么 \([l',r']\) 这个区间完全能代替 \([l,r]\) 转移,因为它的区间长度更短,更容易满足不重合的要求。所以我们只需把所有的 \([l',r']\) 抓出来转移,只要满足 \([l',r']\) 中不存在任意一个子区间和它的 \(\text{MEX}\) 长度相同即可。事实上,这样的区间数量上界是 \(2n\)

所以我们只需处理出所有这样的区间,转移时抓出来转移即可,复杂度 \(O(n^2)\)

H. CF1868C Travel Plan

不愧是 CF 上为数不多的中国人出的题,上一道叫 Jellyfish and EVA。但那道题远不及这道题。

根据我们以前的经验,我们尝试统计每个节点作为最大值的贡献。设一条路径上所有数小于等于 \(x\) 时的方案数为 \(F(x)\),则显然 \(x\) 作为最大值的方案数为 \(F(x)-F(x-1)\),题目要求的答案就是

\[\sum_{x=1}^m\big(F(x)-F(x-1)\big)x \]

考虑怎么求出 \(F(x)\)。观察到 \(n\le10^{18}\)\(m\le10^5\),说明复杂度应该是 \(O(m\log n)\) 左右。考虑 DP。设 \(f_{s,k}\) 表示子树大小为 \(s\)、所有数小于等于 \(k\) 的路径的方案数,\(g_{s,k}\) 表示同样条件下一端是根的路径的方案数。则有

\[\begin{matrix} g_{s,k}=k\times(g_{\mathit{ls},k}\times m^{\mathit{rs}}+g_{\mathit{rs},k}\times m^{\mathit{ls}}+m^{s-1})\\ f_{s,k}=g_{s,k}+k\times g_{\mathit{ls},k}\times g_{\mathit{rs},k}+f_{\mathit{ls},k}\times m^{\mathit{rs}+1}+f_{\mathit{rs},k}\times m^{\mathit{ls}+1} \end{matrix} \]

其中 \(\mathit{ls},\mathit{rs}\) 是左右子树的大小。\(g\) 的转移中要统计左子树小于等于 \(k\) 右子树随便取、右子树小于等于 \(k\) 左子树随便取、路径上只有一个根节点左右子树都随便取的方案数,再乘上根节点从 \(1\) 取到 \(k\) 的方案数;\(f\) 的转移中要统计以根为一端、路径一端在左子树一端在右子树、全在左子树、全在右子树的方案数。

仔细理解这个转移方程之后,我们发现时间可以记忆化搜索,空间会爆炸。但因为它是一棵完全二叉树,所以不同 \(\mathit{ls},\mathit{rs}\) 个数是 \(O(\log n)\) 级别的,可以把原数组的定义改成大小为 \(2^s-1\) 的方案数,这样空间也是 \(O(\log n)\) 的了。

坑点主要在于如何计算左右子树大小。因为是完全二叉树,所以层高差不超过 \(1\),可以先把相同的部分平均分给左右子树,再分剩下的。尽量使用系统自带的 __lg()__builtin_popcountll() 函数,但需要注意判断有没有负数这类的边界情况。

恶心!

I. CF1866M Mighty Rock Tower

原,傻逼推式子题。就它这个状态设计就很神奇,设 \(\mathit{dp}_i\) 为从第 \(i-1\) 个到第 \(i\) 个的期望步数,得

\[\begin{aligned} \mathit{dp}_i&=1+p_i^i\sum_{j=1}^i\mathit{dp}_j+p_i^{i-1}(1-p_i)\sum_{j=2}^i\mathit{dp}_j+\cdots+p_i(1-p_i)\sum_{j=i-1}^i\mathit{dp}_j\\ &=1+p_i^i\sum_{j=1}^i\mathit{dp}_j+\sum_{j=1}^{i-1}p_i^j(1-p_i)\sum_{k=i-j+1}^i\mathit{dp}_k\\ &\qquad\vdots\\ &=\frac1{1-p_i}\left(1+\sum_{j=2}^ip_i^j\mathit{dp}_{i-j+1}\right) \end{aligned} \]

中间的化简过程就不敲了,可以看看这篇里写的,非常详细,很考验推式子功底。

最后得到的式子暴力做是 \(O(n^2)\) 的。看到和式我们很想前缀和优化,但式子里掺杂了一个 \(p_i^j\) 使我们不好处理。但观察到 \(p_i\) 的取值范围只有 \(0\sim99\),所以我们可以针对每一种 \(p\) 都开一个前缀和,然后这题就完了。

J. P10599 BZOJ2164 采矿

题目理解难度远大于题目难度好吧。

路径查询?子树查询?树剖稳了。

至于查询一个子树的最优安排,直接一个树上背包(牢记 \(i,j\) 要从 \(\bf0\) 开始枚举)。

然后路径查询就查询一条路径上的 DP 最大值即可,结合子树查询的 DP 值再进行一次 DP。

没什么可说的了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/874897.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新春“码”启 | 0 基础开发微信小游戏,Cocos 游戏引擎 + AI 辅助编程(第1天)

春节期间,老牛同学计划借助 AI 开启一场挑战自我和为小朋友开发微信小游戏的系列计划,0 基础开始了第1天的体验。目标是采用 Cocos 游戏引擎框架,借助 AI 辅助编程,最终完成微信小游戏研发。目前已对相关概念有了初步了解,后续将持续探索……好羡慕小朋友们,已经放了快两…

grammarly 使用问题

1 Word 使用时,有时下面的图标不出现,无法使用 2 3

那是我们的影子

那是我们的影子 题目描述 由 $3 \times n$ 个单元格构成的 $3$ 行 $n$ 列异形数独规则如下:每一个单元格都需要填入 $1$ 到 $9$ 之间的整数; 任意一个 $3 \times 3$ 的子矩阵中都不包含重复的数字;现在,牛可乐已经填入了一些数字,请你在此基础上帮助他计算,这个异形数独一…

NPS如何安装Windows版的客户端

Windows 首先下载Windows版的客户端: github下载地址:https://github.com/yisier/nps/releases 54 雨云ROS下载地址:https://cn-sy1.rains3.com/rainyun-assets/Pic/2023/11/windows_amd64_client.tar.gz 51我在需要运行NPS客户端的Windows设备的C盘根目录下建立一个名字叫【…

通过宝塔Docker安装NPS客户端

# 拉取 yisier1/npc 镜像 docker pull yisier1/npc安装拉取镜像成功后如下图所示:创建容器: 选择:命令创建 # 运行 npc 容器,按提示改好命令,如下图所示 docker run -d --name=npc --restart=always --net=host yisier1/npc -server=<ip:port> -vkey=<web界面中…

DeepSeekR1本地可视化运行!同时支持GPT4,Gemini,Cluade,Ollama所有开源模型

昨天使用Ollama在本地运行了DeepSeek R1这个可以深度思考的AI模型。通过这种方式可以快速体验模型,但是要长期高频使用的话,通过命令行这种方式终究是不太方便。所以今天来分享一个可视的软件ChatWise。 添加图片注释,不超过 140 字(可选)这是一个独立开发者开发的软件,界…

[ABC266Ex] Snuke Panic (2D) 题解

[ABC266Ex] Snuke Panic (2D) 题解 前言 前几天看到了这个,发现自己还真没仔细思考过。 做了两道题,把这个题当个总结。 思路 设 \(f_i\) 表示:在 \(T_i\) 走到第 \(i\) 个节点的最大收益。 有转移:\(f_i=\max \{f_j\} + A_i\)。 其中 \(j\) 需要满足:\(y_j\le y_i\) \(T_i…

DeepSeek R1果然有点意思! Windows本地使用ollama轻松跑起来。

这段时间国内外讨论DeepSeek的人都比较多,我印象比较深的是,Deepseek用较低的成本训练了一个不错的模型。另一个是说最近的R1可以匹敌chatgpt的o1。 对比chatgpt的模型很多,我也不知道是宣传而已,还是真的这么牛逼。所以准备本地运行一下看看。因为ollama上已经有这个模型了…

跟着狂神学java-第一天

Markdown学习 标题 (一个#+空格,一级标题) 二级标题 (两个#+空格,二级标题) 三级标题 (以此类推。。。) 字体helloworld (两个星号,加粗) hello world ( 一个星号,斜体) hello world (三个*,加粗的斜体) hello world (两个~,删除线) hello world…

36. 打印机

一、打印机应用程序一般都有打印功能,可以将重要内容打印成纸质资料。PySide6 支持打印操作,它可以识别系统中已经安装的打印机,驱动打印机进行工作,可以用与打印机有关的类直接打印,也可通过打印对话框进行打印,还可对打印的内容在打印前进行打印预览。与打印有关的类主…

MiniCPM-o 2.6 本地部署记录,Windows+RTX3060全部跑通!

上一篇中,大致聊了下国产小钢炮MiniCPM的特性,看起来很不错,可玩性很高。今天,主要来说一下,如何在本地运行这个项目。 添加图片注释,不超过 140 字(可选)配置过程花了一些时间,最终还是成功了,可以正常进行视频通话,语音通话,和聊天机器人。安装和测试过程中遇到了…

CTF-web-计算器

1.打开题目2.发现只能输入一个数字 3.查看源代码4.修改参数5.可以正确输入后得到flag