把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

题解P3830 [SHOI2012]随机树

传送门

题意

非常显然。

Question 1

部分分(n10

对于每次长叶子时,就是把一个叶子深度 +1 ,并且复制。
对此可以写出 dfs 暴力 20 分。

整分

可以从上面看出,每次分裂一个叶子,总价值可以增加 (原叶子深度+2)。
由此,令 f[i]i 个叶子时的叶子深度平均值的期望价值。
f[i]×i=f[i1]×(i1)+f[i1]+2
整理可得 f[i]=f[i1]+2i

时间复杂度 O(n)

Question 2

部分分(n10

与上面的dfs大致相同,由于对正解没用,就不赘述。

正解

方法一 O(n4)

对于一棵深度为 deep 的二叉树,
我们可以将其根节点的两棵子树分开,
就会分成一棵深度为 deep1 的二叉树,与一棵深度为 q(1qj1) 的二叉树。

顺着这个思路,我们可以将两个二叉树组合,以变成深度更大的一棵树。
若一棵二叉树深度为 j,另一棵深度为 q
那么两者组合起来的二叉树深度为 max(j,q)+1
且组合起来的树的叶子数量必然大于两棵子树的叶子数。

由此,令 f[i][j] 表示 生成一棵叶子结点为 i 个,深度为 j 的二叉树的概率。
可以写出递推式: f[i][j]=f[k][q]×f[ik][j1]

于是我们可以愉快的 A 掉这题了。

f[1][0]=1;
for(int i=2; i<=n; ++i) {
for(int j=1; j<=i; ++j) {
for(int k=1; k<i; ++k) {
for(int q=0; q<j-1; ++q)
f[i][j]+=f[k][q]*f[i-k][j-1]*2;
f[i][j]+=f[k][j-1]*f[i-k][j-1];
}
f[i][j]/=(i-1);
}
}
db ans=0;
for(int i=1; i<=n; ++i) ans+=f[n][i]*i;
printf("%.6f",ans);

但是我们可以观察到,可以对此代码进行优化。

方法二 O(n3)

在循环 q 时,我们进行了计算了 q=0j2f[k][q]×f[ik][j1]×2
明显的,我们可以对于这一句进行前缀和优化,即可优化至 O(n3)。 同样附上代码:

f[1][0]=1;
qzh[1][0]=1;
for(int i=1; i<=n; ++i) qzh[1][i]=qzh[1][i-1]+f[1][i];
for(int i=2; i<=n; ++i) {
for(int j=1; j<=i; ++j) {
for(int k=1; k<i; ++k) {
if(j>=2) f[i][j]+=qzh[k][j-2]*f[i-k][j-1]*2;
f[i][j]+=f[k][j-1]*f[i-k][j-1];
}
f[i][j]/=(i-1);
}
qzh[i][0]=f[i][0];
for(int j=1; j<=n; ++j) qzh[i][j]=qzh[i][j-1]+f[i][j];
}
db ans=0;
for(int i=1; i<=n; ++i) ans+=f[n][i]*i;
printf("%.6f",ans);

此刻你觉得这道题完了吗,事情并没有如此完结,此题还有一种方法。

方法三 O(n3)

我们稍微改变一下 f[i][j] 的定义,将其定义为叶子数为 i,深度大于等于j 的概率。

由此 f[i][j]=f[k][j1]+f[ik][j1]f[k][j1]f[ik][j1]

稍微解释一下,要么是左子树大于等于 j1,要么是右边,且要减去都大于等于 j1 的概率。

for(int i=1; i<=n; ++i) f[i][0]=1;
for(int i=2; i<=n; ++i) {
for(int j=1; j<i; ++j) {
for(int k=1; k<i; ++k)
f[i][j]+=f[k][j-1]+f[i-k][j-1]-f[k][j-1]*f[i-k][j-1];
f[i][j]/=(i-1);
}
}
db ans=0;
for(int i=1; i<=n; ++i) ans+=f[n][i];
printf("%.6f",ans);

完结撒花!!!

posted @   djh0314  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示