AtCoder Beginner Contest 395
ABC395
Resources
Submission (A~E)
F Solution
如果只有第一个限制,那么求出 (下文用 代替),将所有 的都修剪一下就好了。
如果只有第二个限制,可以用优先队列,将所有 扔到队列中,每次取出最短的牙齿(设其为 ),然后检查这个牙齿相邻的两个牙齿 和 ,检查它们是否满足 和 (显然 )。如果不满足,例如 ,那么令 。
可以证明这个修剪是必要的:因为不可能存在一种合法情况满足 ,说明 一定要被修剪。
当然,更新完之后要把这些修剪后的牙齿塞回优先队列。显然,每个 最多只会被塞入队列 3 次(初始化、被左边的牙齿更新、被右边的牙齿更新)。时间复杂度是 。至此,就解决完第二个限制了。
我们考虑在第二个限制的基础上加上第一个限制。假设所有牙齿已经被上述过程修剪过了(称为第一次修剪),我们得到了序列 。此时求出 和 。可以证明, 就是题目所说的 。证明如下:
如果 ,那么我们只需要把 减少即可。
否则,存在一些位置 满足 ,我们只需要把这些位置的牙齿修剪即可 (称为第二次修剪)。我们得到一个新的序列
第二次修剪是否会破坏第二个限制呢?答案是不会的。
反证法。假设第二次修剪导致第二个限制被破坏了,即,存在某个 ,在它被修剪后,它和相邻的牙齿高度差大于 。
- :不可能,因为第二次修剪后,所有 都应该小于等于 。
- :不可能,因为假设不等式成立,说明 没有在第二次修剪被剪掉,即 。我们知道 ,则有 。但我们知道第一次修剪后有 ,矛盾。
我们证明了第二次修剪保持了第二个限制的成立性,并且保证了第一个限制的成立,故此构造是合法的。
G Solution
还是考虑用最小斯坦纳树的算法。
此算法求出了 表示以 为根,包含集合 内所有节点的最小斯坦纳树的代价。空间大小是 的
假设只有 ,那么直接回答 即可,其中 表示包含 的全集。问题在于本题是 。
不难注意到 比较小(),那么可以考虑一个更大的集合 :
二元组 表示 集合和 号节点在最小斯坦纳树上,当 等于 时表示只有 在最小斯坦纳树上。可以发现这个集合的大小是 的。最后仍然使用 设计 dp 状态,保证 即可。状态空间的大小是 的。回答的时候只需要回答 。
最后分析时间复杂度,大概是 的。
本文来自博客园,作者:lingfunny,转载请注明原文链接:https://www.cnblogs.com/lingfunny/p/18746494
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】