zoukankan      html  css  js  c++  java
  • 【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles

    期望计算的套路:

    1、定义:算出所有测试值的和,除以测试次数。

    2、定义:算出所有值出现的概率与其乘积之和。

    3、用前一步的期望,加上两者的期望距离,递推出来。

    题意:

    一个树,dfs遍历子树的顺序是随机的。所对应的子树的dfs序也会不同。输出每个节点的dfs序的期望

     

    思路:

    分析一颗子树:

    当前已知节点1的期望为1.0 ->anw[1]=1.0

    需要通过节点1递推出节点2、4、5的期望值

    1的儿子分别是2、4、5,那么dfs序所有可能的排列是6种:

    1:1-2-4-5  (2、4、5节点的儿子没有写出)

    2:1-2-5-4

    3:1-4-2-5

    4:1-4-5-2

    5:1-5-2-4

    6:1-5-4-2

    计算节点2的期望值得时候,当节点2的前面已经排列了num个点,那么节点2的dfs序就要增加num

    所以anw[2]的计算分为两部分,第一部分是:anw[2]=anw[1]+1  (节点1通过1步直接到达儿子2、4、5)

    第二部分是:当节点1到达节点2的时候贡献是0,种类分别对应(1、2)

          当先到达节点4后到节点2的时候贡献(size(4)+size(4)+szie(5)),种类分别对应(3、4)

          当先到达节点5后到节点2的时候贡献(size(5)+size(5)+size(4)),种类分别对应(5、6)

    而所有的排列对于的概率都是1/6,所以第二部分的贡献就是(0+size(4)*3+size(5)*3)/6 = (size(4)+size(5))/2

    仔细推理几颗子树之后:发现anw[v]=anw[u]+1.0+(sz[u]-sz[v]-1)/2.0。

    anw[u]+1.0对应第一部分  (sz[u]-sz[v]-1)/2.0 表示的是当前能排在节点v前面的u的儿子的总数  *  0.5

    对比1-6的6种排列,任意儿子a、b  ,满足a在b前面的概率是0.5  

    转自http://blog.csdn.net/libin66/article/details/51918509

    代码懒得写了,转自同源:

    #include<iostream>  
    #include<cstdio>  
    #include<cstring>  
    #include<algorithm>  
    #include<string>  
    #include<vector>  
    #include <ctime>  
    #include<queue>  
    #include<set>  
    #include<map>  
    #include<stack>  
    #include<iomanip>  
    #include<cmath>  
    #define mst(ss,b) memset((ss),(b),sizeof(ss))  
    #define maxn 0x3f3f3f3f  
    #define MAX 1000100  
    ///#pragma comment(linker, "/STACK:102400000,102400000")  
    typedef long long ll;  
    typedef unsigned long long ull;  
    #define INF (1ll<<60)-1  
    using namespace std;  
    int n;  
    struct edge{  
        int v,next;  
    }e[500100];  
    int head[100100],tot=0;  
    void Add(int u,int v){  
        e[tot].v=v;  
        e[tot].next=head[u];  
        head[u]=tot++;  
    }  
    int sz[100100];  
    void DFS(int u,int fa){  
        sz[u]=1;  
        for(int i=head[u];i!=-1;i=e[i].next){  
            int v=e[i].v;  
            if(v==fa) continue;  
            DFS(v,u);  
            sz[u]+=sz[v];  
        }  
    }  
    double anw[100100];  
    void DFS1(int u,int fa){  
        for(int i=head[u];i!=-1;i=e[i].next){  
            int v=e[i].v;  
            if(v==fa) continue;  
            anw[v]=anw[u]+1.0+(sz[u]-sz[v]-1)*1.0/2.0;  
            DFS1(v,u);  
        }  
    }  
    int main(){  
        mst(head,-1);  
        scanf("%d",&n);  
        for(int i=2;i<=n;i++){  
            int x;  
            scanf("%d",&x);  
            Add(x,i);  
            Add(i,x);  
        }  
        DFS(1,0);  
        anw[1]=1.0;  
        DFS1(1,0);  
        for(int i=1;i<=n;i++) printf("%.2f ",anw[i]);  
        return 0;  
    }  
  • 相关阅读:
    POJ1125-Stockbroker Grapevine【Floyd】(模板题)
    Codeforces 862B (二分图染色)
    hdu3047 Zjnu Stadium【带权并查集】
    HDU1532 网络流最大流【EK算法】(模板题)
    hdu 2063 过山车【匈牙利算法】(经典)
    HDU-2066-一个人的旅行 【Dijkstra】
    HDU 3625 Examining the Rooms【第一类斯特灵数】
    HDU4372-Count the Buildings【第一类Stirling数】+【组合数】
    HDU 6114 Chess【逆元+组合数】(组合数模板题)
    HDU1211 密文解锁 【扩展欧几里得】【逆元】
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/5680492.html
Copyright © 2011-2022 走看看