zoukankan      html  css  js  c++  java
  • 【洛谷P3830】随机树

    题目

    题目链接:https://www.luogu.com.cn/problem/P3830

    思路

    期望\(dp\)萌新。

    先考虑第一问。我们设\(f[i]\)表示有\(i\)个叶节点时,叶子结点的期望深度。
    我们知道所有叶子结点的期望深度之和为\(f[i]\times i\)。那么当有\(i-1\)个叶子结点时,我们在叶子结点中随机展开一个,叶子深度之和就变为了\(f[i-1]\times (i-1)+2\times (dep[x]+1)-dep[x]\)
    其中\(2\times (dep[x]+1)-dep[x]=dep[x]+2\),而\(dep[x]\)的期望为\(f[i-1]\),所以叶子深度之和就是\(f[i-1]\times i+2\)
    所以有

    \[f[i]\times i=f[i-1]\times i+2 \]

    \[f[i]=f[i-1]+\frac{2}{i} \]

    第二问。我们设\(f[i][j]\)表示有\(i\)个叶子结点,树的深度不小于\(j\)的概率。
    那么有

    \[f[i][j]=\sum^{i}_{j=1}\sum^{i}_{k=1}\frac{f[k][j-1]+f[i-k][j-1]-f[k][j-1]\times f[i-k][j-1]}{i-1} \]

    具体原因请看这篇题解qwq,是看这篇题解的,直接把他的证明方法抠过来也不好。
    试图掩盖自己太菜的事实qwqwqwq,不过这篇讲的是真的很好

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N=110;
    double ans,f[N][N];
    int n,opt;
    
    int main()
    {
    	scanf("%d%d",&opt,&n);
    	if (opt==1)
    	{
    		f[2][1]=1.0;
    		for (int i=3;i<=n;i++)
    			f[i][1]=f[i-1][1]+2.0/i;
    		printf("%0.6lf",f[n][1]);
    	}
    	else
    	{
    		f[1][0]=f[2][0]=f[2][1]=1.0;
    		for (int i=3;i<=n;i++)
    		{
    			f[i][0]=1.0;
    			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]/=(double)(i-1);
    			}
    		}
    		for (int i=1;i<n;i++)
    			ans+=f[n][i];
    		printf("%0.6lf",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    时间日期事件处理、长按事件
    单选按钮触发事件、下拉列表触发事件
    事件
    笔记3
    笔记2
    笔记1
    布局管理器
    08、shell三剑客之sed
    07、shell三剑客之grep
    06、shell正则表达式
  • 原文地址:https://www.cnblogs.com/stoorz/p/12103315.html
Copyright © 2011-2022 走看看