DP(动态规划)
中规中矩的一场模拟赛。
T1 写得实在是太久了……这也是没办法的事情——如果不对转移作压缩优化就没办法过。
T2 有我喜欢的马拉车 Manacher 算法,是印象里第二次在模拟赛应用。
然后就没时间了。后两题仍然只有暴力分,但最近频繁遇到跟凸包和线性函数相关的题目,这使我发现 T3 跟它相关。在最后一点时间里实现了构建凸包的函数。代码本身没问题,但思路是错误的。
简略题解
A – 石蒜反冲
这好像是很早以前的译名了。现在它叫《莉可丽丝》。
遇见多模式串匹配,自然想到自动机上 DP。但我们发现题目中给定的两个串 sakana
chinanago
在任何一个文本串中最多只能匹配其中一个,且匹配位置唯一。于是简单计数 DP 转移,记录当前二者匹配数之差与目前匹配位置即可。
一些不应用就过不了的优化:
- 二者数量之差可只记录到 。 是两个串的总长度。
- 转移时对于
?
s
c
a
o
还有其他字符分类讨论,保证单次转移复杂度为 。
时间复杂度 。 (更多…)
感冒咳嗽,头实在是太晕了,打完前两题和后两题的暴力之后跑去睡了会觉。结果考得还行。
一句话题解
A – 破坏
简单的 DP。记录每个节点的路径数奇偶性考虑是否翻转即可。
B – 共识
用 std::bitset
写的暴力大家都会。不过如果你胆子大些,不判断是否为部分分数据范围直接提交(加入随机化的)暴力,将喜提 。
命题:现有一个由 个元素构成的集合,保证 。有 个大小恰为 的子集 。则至少存在 对无序对 ,使得 。
证明(引自宋佳兴学长):记元素 在所有子集中出现的次数为 。则显然有“所有子集两两之交的大小”
考虑计算该式最小为何。不妨先考虑 在何时取最小值。
引理: 在 处取最小值。
签到题看了半个小时;T2 没有考虑到只需要包含最优解即可,非要确定另一多余状态,只拿了部分分。
T3 只会考虑 “ 的公共祖先中含有 的概率”,不会高效计算“当二者的 恰为 时”的期望/概率与总长之和的乘积,仍然只有暴力分。
T4 无思路。
一句话(?)题解
A – 签到题
可以简单用归纳法证明,仅有所有管道中通行时间最大的会阻塞进度,是为两数据包到达终点的时间间隔。算出首个数据包到达的时间再将前者相加即可。
B – 简单题
第一反应是类似笛卡尔树一样,在区间上依次合并区域最大值并计算贡献。 似乎也在暗示这是一个区间 DP。
做法
设 表示“考虑完成区间 内所有贡献,且最大值恰好为 ”的最大权值和。转移时从小到大枚举最大值 ,枚举包含它的区间,尝试转移 ,其中 计算 ,可以由二维前缀和实现。稍加演算会发现,这样转移不会重复计算贡献。时间复杂度 。 (更多…)
SOS Dynamic Programming [Tutorial] – usaxena95 on CodeForces
通过优化,将子集求和类相关问题的时间复杂度由朴素的 优化到 。
CodeForces Round #755 Div.2 F / Div.1 D Serious Business
此题整整困了我一天半,耗费了好几张草稿纸。实在走投无路,翻看题解,却发现正解曾经近在咫尺。有必要稍作整理。
考虑DP。
错误转移1
这道题与清理班次(《算法竞赛进阶指南》上的一道例题)过于相似,都是“给定一些段落,选择其中一些完整覆盖,求最小花费”的形式。记上述花费为。但本题与原题不一样之处在于其起点和终点是任意给定的。我的第一反应是枚举在位置从第行转到第行,利用数据结构维护所有,在转移到第二行,解锁到达的最小代价。对于各行前缀和,我们可以利用线段树或树状数组维护。同时我们也知道可以利用数据结构优化在的时间内,计算出对于一个固定的起点,所有的值。 (更多…)
被这玩意卡了一上午——前天CSP-S模拟的T4需要用到这类问题的转移。为什么题解TMD是错的?
即表示“每个位置有类元素可选,且序列中必须包含指定的类元素的,长度为的序列的个数”。形式化地讲,我们需要统计满足以下条件的序列的个数:。
通过容斥原理,我们可以计算出至少有个中的元素没有被包含在序列中的序列的个数,然后乘上容斥系数累加既是答案。也即:
。通俗地讲,我们在 个元素中选择 个,并强制使得它们不出现在序列中,其余元素任选。除去组合数的预处理时间,复杂度为。参阅AtCoder ABC 194 F – Digits Paradise in Hexadecimal,可以使用上述计算而非DP求解(虽然DP更加简洁直观)。