CSP-S2019 题解

做了这套题,如果是让现在的我当时去考的话应该一共可以有 450 分,格雷码,括号树,树的重心都可以做,树上的数可以有 10 分,Emiya 至少可以有 76 分, 划分也可以有 64 分。看 OIerDB 上可以有 166 名的好成绩。

我的代码合集:洛谷 / 云剪贴板

[CSP-S2019] 格雷码

首先是格雷码有一个很好的生成方式,最低位 0110 的循环,次高位 00111100 的循环……

也就是说第 i 位由 2i02i+11,再来 2i0 来循环,并且这与总共有多少位是没有关系的!

那么我们就可以利用这个方法生成给定的第 k 个数,输出前 n 位即可。

[CSP-S2019] 括号树

首先我们考虑只有一条链怎么做。

() 看作 1/1,做出前缀和序列。

那么对于每一个区间 [l,r],为合法括号序列当且仅当 prel1=prer 并且 minlir=prer

于是可以利用单调栈,对于每一个右端点找到满足第二个条件的区间(也就是在前面第一个 <prer 后的左端点都满足第二个条件),顺便记录一下与栈顶相等的数的个数即可。

如果放在树上,我们只需要一个支持撤销的栈即可。

[CSP-S2019] 树上的数

抽象题,我只会 n! 和菊花图的做法 QwQ

[CSP-S2019] Emiya 家今天的饭

首先有一个很 naiveO(mn3) DP,稍稍卡常应该是完全可以过的。

具体来说,我们发现之多只有一个不满足 k2 的食材,那么我们枚举这个食材是什么即可。

接下来,我们设 fi,j,k 表示对于这个食材,考虑了前 i 种烹饪方法,选择了 j 种这个食材,一共选择了 k 种。那么枚举这一次的选择就可以转移了。

Si 表示第 i 种烹饪方式有多少种选择,即 Si=ai,k,如果当前食材为 z,那么转移为:

fi,j,k=fi1,j,k+fi1,j1,k1×ai,z+fi1,j,k1×(Siai,z)

最后我们只需要 j>k2fn,j,k 即可。

然而这极度不优秀,将 jk2 转化为 j>kj,那么我们只需要 j>kjfn,j,k 即可,也就是我们只关注 j(kj) 的差值,那么我们按照这个作为 DP 对象即可。

fi,d=fi1,d+fi1,d1×ai,z+fi1,d+1×(Siai,z)

这就是 O(mn2) 的了,可以过。

[CSP-S2019] 划分

首先,O(n2) 的 DP 是简单的,我们只需要记录 fi 表示最小代价,gi 表示使得为最小代价最后一段的最小值。

然而我们需要 O(n) QwQ,于是考虑 a2+b2(a+b)2,也就是我们需要使得划分出的段最多,那么只需要利用一个单调队列即可。

具体来说,我们需要找到 gjpreiprej 的最大的 j,也就是 gj+prejpreij 即可,由于 prei 是单调的,这容易利用单调队列维护。

[CSP-S2019] 树的重心

见我的另一篇文章:[CSP-S2019] 树的重心 题解

posted @   jeefy  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示