noip模拟19/20

这两场考试大部分的题都考过,然鹅有的 trick 忘了,有的当时咕了(虽然现在还咕着

首先是 v 这道题需要加一个小优化,对于较小的状态应该直接用数组记录,较大的再用 map 记

然后就是这个神奇的 dp 题:


A. 玩具

考场上只会暴搜,胡了一个 hash 还给挂了
正解是神奇的 dp

首先核心是 f[i][j] 表示 i 个点的树深度为 j 的概率,那么期望即概率乘深度之和
考虑这个怎么转移:
如果想办法从 f[i1][k] 转移,可以发现这个状态是不完备的,因为不知道 i1 个点深度为 k 时各个深度的点各有多少个,那么加在每个深度的概率是不相同的
那么考虑这棵树最后加入的点是树顶那个点
因为树顶那个点加入前整个的深度是固定的为 j1

那么问题又来了,如果加入的是树顶,那么原来所有的子树将形成一个森林,显然还需要一个变量维护森林的状态
那么设 g[i][j] 表示 i 个点的森林深度为 j 的概率,那么有

f[i][j]=g[i1][j1]

接着考虑 g 的转移,可以想到从一部点形成的树外加另外的点形成森林来转移
假设树的大小为 k,那么一部分是 f[i][k],发现另一部分的深度是不确定的,只要小于等于 j 即可

说明状态设计的有问题,那么设计成深度小于等于 j 就好了
f 的转移还是一样的
然后再看 g 的转移,发现还是有 bug,因为总共有 j 个点,有 k 个点在第一棵树里,这是有概率的,那么继续打补丁——设 dp[i][j] 表示 i 个点的森林有 j 个点在第一棵树的概率
考虑转移,从 dp[i1][] 转移而来,分为新加的点在不在第一棵树里两种情况,方程式为:

dp[i][j]=dp[i1][j1]j1i+dp[i1][j]iji

这里需要注意看似上一种情况共可以向 i1 个点连边,为什么分母上是 i 呢?
因为漏掉了一种情况就是新加的这个点其实是可以自成一棵树的,所以没有问题

这回终于可以转移 g 了:

g[i][j]=k=1if[i][k]g[i][ik]dp[i][k]

最后是统计答案,由于状态设计的是前缀和形式,那么答案需要减一下,即:

i=1n(f[n][i]f[n][i1])i

update:注意表达式中的 f[i][j] 全部为深度小于等于 j 的树,g[i][j] 表示小于等于 j 的森林
并且通过实践验证 dp[i][j]=1i,可能这个确实是等概率事件吧

posted @   y_cx  阅读(28)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示