洛谷P3830 [SHOI2012]隨機樹-期望DP
阿新 • • 發佈:2019-02-10
題意:
一棵含有n個葉子節點的二叉樹通過如下方式生成:
每次等概率的隨機選擇一個葉子節點,將這個節點加上左右兩個子節點
求:
1.葉子節點平均深度的期望
2.樹深度的期望
Solution:
第一問很好處理:設表示有x個葉子節點的樹的葉子節點平均深度
我們考慮在一個有x-1個葉子節點的樹裡隨機選擇一個葉子節點展開,那麼樹的葉子節點深度總和會增加
所以
第二問就比較難受了:
首先我們知道一個式子:
說人話就是隨機變數x的期望為對於所有i,的概率之和
我們設表示有i個葉子,樹的深度的概率
轉移時列舉左右子樹有多少個葉子:
(括號裡的式子含義:左右只要一邊深度即可,所以式子展開其實是,但這樣會計算兩次兩邊都的情況,所以需要減掉)
最後答案即為
程式碼:
#include<cstdio>
#include<iostream>
using namespace std;
int p,n;
double f[110],dp[110][110],ans;
int main()
{
scanf("%d%d",&p,&n);
if (p==1)
{
f[1 ]=0;
for (int i=2;i<=n;i++) f[i]=f[i-1]+2.0/i;
printf("%.6f",f[n]);
}
else
{
for (int i=1;i<=n;i++) dp[i][0]=1;
for (int i=2;i<=n;i++)
for (int j=1;j<i;j++)
{
for (int k=1;k<i;k++)
dp[i][j]+=dp[k][j-1]+dp[i-k][j-1]-dp[k][j-1]*dp[i-k][j-1];
dp[i][j]/=(i-1);
}
for (int i=1;i<n;i++) ans+=dp[n][i];
printf("%.6f",ans);
}
}