杭州集训 Day 3
课前
早饭 htdlz 帮忙买的,一碗粥和三个不知名的糕点,粥并不好喝,但是糕点好吃。
早上到了机房把这儿的小破电脑换成了自己的笔记本,屏幕大一点舒服一些。hs_black 走了,今天换 syksykccc 来讲,syk 开朗幽默的多,上课和机房这群很有话题。而且他甚至把他讲的每个题对应的代码打了,然后课后发了。
课前他自我介绍说:“我是高一拿的 Ag,后来觉的 OI 比 whk 难然后就 AFO 了,最后裸分考的北大。”
syk 还发表了一些逆天言论,如 “破链为环” 解决区间 dp 问题
笔记
P2051
设 表示从左上角一直到坐标 并且用了 ~ 个象棋的方案数
的数据范围很小,可以 暴力遍历
标记棋子
但是转移并不好写,考虑找性质,发现对于每行每列炮的个数不会超过两个
所以将第二,三维优化
表示 有 个列是 个炮, 表示有 个列放 个炮,剩下的放 个炮
转移的时候就考虑在当前行放 个炮,以及这些炮放在了之前有几个炮的列上
现在可以暴力转移,复杂度三次方级,可以通过
P1437
将原图形旋转变成左下角为直角的等腰直角三角形形式,那么想要拿走一个砖,就必须要拿走左边那个和左上角那个,考虑有依赖的背包 dp
显然的,可以将当前砖和左边那个和左上角那个绑定,他们的分值和为质量,个数为体积,然后背包
但是一定会有重复绑定导致计算错误,所以要考虑找特殊性质,发现第 行被打掉的一定是一个前缀,用 表示当前考虑到第 行,这一行的轮廓线转折点在 ,已经打了 个砖头的最大收益。
复杂度
P6189
显然可以平方级别的背包 dp,但是显然过不了。但是对于背包 dp 它也有两种不同的状态设计,
表示把 拆成 的数的方案。 表示把 拆成 个数的方案。这个直接递推转移是非常好实现的。
之后根号分治,对于小于等于 的数据计算 ,剩下的计算 (这里数据指的是 dp 第二维)
复杂度
之后考虑如何使用 更新计算答案
指的是根号分界
P7962
将答案式子展开化简后为
对于一次操作,原来相邻两个数的差为 变为了 。即一次操作是在交换差分数组的相邻两项,
可以任意交换差分数组得到一个新的差分排列。为了使所有数字趋于平均值,差分数组应当是单谷序列,微扰法可以证明。将差分数组 从小到大排序,然后依次考虑每一项,要么插在当前最左边,要么插在当前最右边。
令 ,设 表示考虑了前 个数,当前
的情况下,最小的 是多少。
-
,放在右边
-
,放在右边
直接 dp 复杂度为
注意到差分数组中非 项至多 个,而对于 毕竟排在最前面,无论放左放右都是一样的,所以直接铺开就行了,于是时间复杂度就能做到
P6764
计算出 表示能否从 开始进行一次粉刷,之后的就是很平凡的贪心区间覆盖问题。
假设现在 ,那么每个墙能指派的承包商是固定的。用 表示从第 段墙开始最远能刷到哪里。
用 表示从第 段墙开始,让承包商 来粉刷,最远能刷到哪里。可以 逆序递推。初始化 ,对于 的情况,。剩下的 的情况
然后还有一些优化的 trick 卡一下就过了
P5289
用 这样的状态去做背包,表示考虑到当前学校的时候,红阵营有 人, 派系有 个人的方案数。复杂度是
假如 发现可以先计算阵营的分配方案数,再计算派系的方案数,然后把两个乘起来即可。这两个都是可以一维背包实现的,复杂度
对没有限制的学校用分别 的方式,对于有限制的学校,因为不超过 个,所以用二维 的方式再合并一下答案,总复杂度
P4302
用 表示 的答案。
-
第一条:
-
第三条:
-
第二条:枚举循环节长度 ,
枚举 是 的因子的去检查,调和级数可得复杂度
P6879
时间值域太大了,不好设计进状态,但是答案很小,考虑交换定义域和值域设计 dp 状态。
表示当前考虑了 这一段的所有打卡点,
表示终止时站在 还是 ,真正成功打卡了 个点时,最小花费的时间。用每一个已经求出的 的状态去更新 和 。 是否要增加可以根据两个 的值很方便地计算。
那么初始时把所有的状态都赋值为无穷,如果一个状态的最小时间不是无穷就说明有意义,用它去刷表。最后要查看有意义的状态的 的最大值。
复杂度
P1864
不能修改数据值,所以这棵树的中序遍历固定。另一点是,由于可以修改为任意实数,实数是可以无限接近但是不相等的,所以完全可以理解为,允许权重相同,并且权重相同的点可以以任何你想要的顺序排序。即允许假定权重是整数来考虑这个问题。用 表示把 建树并且保证子树内所有点的权重都 的时候,最小化的答案。 通过枚举根节点 ,分别考虑不需要 /需要修改,利用下两式来更新
其中 表示深度 之后代价的增量。总复杂度为
P7605
设 为答案
转移 考虑第一步选择了左边还是右边,不妨设左边。
如果最终都没消去,那么就是
如果最终利用 消去了,考虑一下 是从左端取出的还是
从右端取出的。
不妨设是右端取出的,那么显然 要先被删除,考虑
枚举 表示 辅助了这一段的删除,那么转化后的子
区间就是
用 来表示这个转移
其中 表示完全消除 所需要的栈的大小。当然也有可能为无穷,此时对应的状态不能用来转移
。
关于 的转移,考虑是先取出 还是 。
比如是 ,考虑它和哪个位置配对,比如是和 ,其中 。再枚举左侧辅助消除 的区间是 ,那么转移就可以表示为
理论复杂度 ,实际上可以快速判断一些 的值为无穷,比如区间长度和是否为偶数,区间内的数是否两两配对(可以哈希之后求异或
和)。这样常数很小。可以用记忆化搜索实现。
P7077
如果没有第 类,考虑计算每个第 类函数的实际被调用次数。
第 类函数可以看作,对原始数据的乘法 + 将之前的第 类函数调用 次。
建立一个 ,每个第 类函数(可以把 也建模成一个第 类函数)向它所调用的所有函数依次连边。
首先考虑计算原始数据的贡献,这个只需要一次 dp 求出每个函数调用造成的全局乘积大小,然后就可以方便的计算总倍率。
逆序第 类函数序列。动态维护一个乘积 表示当前子函数需要执行多少次。每遇到一个子函数,就在它对应的节点上打 标记,然后再更新 。这样便可以拓扑排序后利用 dp 求出每个函数需要调用的次数,累加贡献。
复杂度
P4577
每个节点开一个 multiset
,从大到小的第 个数,表示当答案为 时的最大转移权值。
首先不考虑 的话,
考虑 ,那么把 插入 ,然后除非 是 中最小的,否则把 的前一个 iterator
删除。合并 时可以使用启发式合并,复杂度 ,如果使用权值线段树维护可以做到单
P5024
设 表示 的子树, 不选 / 选,从“转移模式”来
看,除了 ,其他的点依然在做相同的操作。
首先一次 求出前文提到的 数组,现在考虑把 倍增化。用 表示对于 ,它选不选,它的 级父亲 选不选,则 的最优代价。初始化为
倍增转移时枚举 级父亲的状态
现在分两种情况讨论询问。如果 是祖先-后代关系,那么,先用 的 去初始化状态 ,分别表示当前的根节点是不选/选的最小代价。然后用 去倍增到 ,再把 赋值为 ,最后一路倍增到根节点即可。如果不是的话,同理,分别从 用上面的操作倍增到 LCA 下方的节点,然后在 LCA 处暴力合并答案,再倍增到根节点即可。复杂度只有一个
课后
绝区零常驻池第一个常五是狼哥,第二个十连出了苍角,抽那个小不点不知道是什么的东西上来十连出了一个金,后来换成鲨什么蓝色的那只十连又出了。
暗示我抽鲨鱼妹
但是我 50 抽了还没出,运气太差
傻鸟米哈游不如洛谷好玩
本文作者:PassName
本文链接:https://www.cnblogs.com/spaceswalker/p/18494373
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步