zoukankan      html  css  js  c++  java
  • CF696B Puzzles(期望dp)

    传送门

    解题思路

      比较有意思的一道题。首先假如这个点(x)只有(1)个儿子(u),那么显然可得(dp[u]=dp[x]+1)。继续如果多加一个儿子(p),那么(p)(u)前面的概率就是(1/2),也就是说(p)对于(u)的答案有(1/2)的可能产生贡献,而产生的贡献为(siz[p]),那么继续归纳下去,就可以得出转移方程。(dp[u]=dp[x]+1+(siz[x]-siz[u]-1)/2)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 100005;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,head[MAXN],cnt,to[MAXN],nxt[MAXN],siz[MAXN];
    double ans[MAXN];
    
    inline void add(int bg,int ed){
        to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void dfs1(int x){
        int u;siz[x]=1;
        for(int i=head[x];i;i=nxt[i]){
            u=to[i];dfs1(u);
            siz[x]+=siz[u];
        }
    }
    
    void dfs2(int x){
        int u;
        for(int i=head[x];i;i=nxt[i]){
            u=to[i];ans[u]=ans[x]+1+(double)(siz[x]-siz[u]-1)/2;
            dfs2(u);
        }
    }
    
    int main(){
        n=rd();int x;
        for(int i=2;i<=n;i++)
            x=rd(),add(x,i);
        ans[1]=1.0;dfs1(1);dfs2(1);
        for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]);
        return 0;
    }
    
    
  • 相关阅读:
    Android学习地址
    Android动画设计源码地址
    chromeWebBrowser之浏览器开发
    win8.1蓝屏解决
    打包应用程序
    win8.1解决鼠标右键反应慢的问题
    Rewrite服务器和robots文件屏蔽动态页面
    第08组 Alpha事后诸葛亮
    第08组 Alpha冲刺(6/6)
    第08组 Alpha冲刺(5/6)
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10050817.html
Copyright © 2011-2022 走看看