zoukankan      html  css  js  c++  java
  • 洛谷3830 [SHOI2012]随机树 【概率dp】

    题目

    输入格式

    输入仅有一行,包含两个正整数 q, n,分别表示问题编号以及叶结点的个数。

    输出格式

    输出仅有一行,包含一个实数 d,四舍五入精确到小数点后 6 位。如果 q = 1,则 d 表示叶结点平均深度的数学期望值;如果 q = 2,则 d 表示树深度的数学期望值。

    输入样例

    1 4

    输出样例

    2.166667

    提示



    题解

    第一问比较简单,我们设(f[i])表示第(i)次扩展的期望深度
    那么

    [f[i] = frac{f[i - 1] * (i - 2) + (f[i - 1] + 1) * 2}{i} ]

    化简得

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

    第二问
    首先我们有这样一个整数概率公式:

    [E(x) = sum_{i = 1}^{+infty} P(x >= i) ]

    含义为:随机变量(x)的期望为所有(x>=i)的概率之和

    那我们设(f[i][d])表示有(i)个叶子,深度(>=d)的概率,
    那么

    [ans = sum_{i = 1}^{n - 1} f[n][i] ]

    考虑转移,我们枚举左右子树分到多少叶子

    [f[i][d] = sum_{j = 1}^{i - 1} frac{f[j][d - 1] + f[i - j][d - 1] - f[j][d - 1]*f[i - j][d - 1]}{i - 1} ]

    其实就是一个容斥,两边都大于(d - 1)的部分会被算两次,减去一次即可

    这样我们就做完了

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 205,maxm = 100005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    double f[maxn][maxn];
    int n,t,m;
    void solve1(){
    	double ans = 0;
    	for (int i = 2; i <= n; i++){
    		ans += 2.0 / i;
    	}
    	printf("%.6lf
    ",ans);
    }
    void solve2(){
    	for (int i = 1; i <= n; i++) f[i][0] = 1;
    	for (int i = 2; i <= n; i++){
    		for (int d = 1; d < i; d++){
    			for (int j = 1; j < i; j++)
    				f[i][d] += (f[j][d - 1] + f[i - j][d - 1] - f[j][d - 1] * f[i - j][d - 1]) / (i - 1);
    		}
    	}
    	double ans = 0;
    	for (int i = 1; i < n; i++) ans += f[n][i];
    	printf("%.6lf
    ",ans);
    }
    int main(){
    	t = read(); n = read();
    	if (t & 1) solve1();
    	else solve2();
    	return 0;
    }
    
    
  • 相关阅读:
    兼容性处理
    H5 IOS 虚拟键盘不回落的问题
    git 的版本控制
    vue-devtools工具的安装
    linux下安装mysql
    Python安装pip3常见问题
    linux下安装python3
    接口_注册接口
    接口_简单get接口_第一个接口
    Python学习笔记_Redis
  • 原文地址:https://www.cnblogs.com/Mychael/p/8733095.html
Copyright © 2011-2022 走看看