zoukankan      html  css  js  c++  java
  • [题解]HDU4035 Maze

    题目描述

    一棵(n)个节点的树,从1号结点开始游戏,在每一个点(x)

    • (a[x]/100)的可能掉进陷阱死翘翘回到1重新开始
    • (b[x]/100)的可能找到出口并结束游戏
    • 剩下的可能中,你等概率随机选一条和它相连的边(可以是父亲)走过去

    问期望多少步结束游戏

    (1leq T leq 30,1leq n leq 10000)

    分析

    (dp[x])表示位于(x)节点时,期望走几步才能结束游戏

    那么(dp[x]=0.01a[x]*dp[1]+0.01b[x]*0+0.01(1-a[x]-b[x])*(frac{1}{cnt}(sum dp[son]+dp[1]+1)))

    看了一下数据范围发现并不能承受高斯消元的时间复杂度

    我们发现,每一个点的(dp)值之和父亲、1号点还有儿子有关,那么叶子节点的(dp)值可以用父亲和1号点表示,这样往上代,合并同类项之后可以发现,每一个点的值都可以表示为:

    (dp[x]=...*dp[1]+...*dp[fa[x]]+...)(常数项)

    所以只需要维护一下每一项的系数就可以(O(n))求解了,记得特判Impossible

    代码

    void SEARCH(int x,int pa){
    	f[x][0]=f[x][1]=f[x][2]=0;
    	int cnt=0;
    	for(int r=lst[x];r;r=nxt[r]){
    		cnt++;
     		if(edge[r]==pa)continue;
    		SEARCH(edge[r],x);
    	}
    	DB lef=(100-a[x]-b[x])*0.01;
    	DB hlp=0;
    	for(int r=lst[x];r;r=nxt[r]){
    		if(edge[r]==pa)continue;
    		int pos=edge[r];
    		f[x][0]+=f[pos][0];
    		f[x][2]+=f[pos][2];
    		hlp+=f[pos][1];
    	}
    	f[x][0]=(lef*f[x][0])/(1.0*cnt)+a[x]*0.01;
    	f[x][2]=(lef*f[x][2])/(1.0*cnt)+lef;
    	if(x==1)f[x][1]=0;else f[x][1]=lef/(1.0*cnt);
    	hlp=hlp*lef/(1.0*cnt);
    	hlp=1.0-hlp;
    	if(x==1)hlp-=f[x][0];
    	if(hlp<=0)f[x][0]=f[x][1]=f[x][2]=0;
    	else rep(i,0,2)f[x][i]/=hlp;
    }
    
  • 相关阅读:
    VUE DEVTOOLS 安装方法(npm cnpm 安装失败找不到安装工具问题解决方法)
    idea 注释模版
    阿里巴巴编码规范
    JRebel 实现热部署
    SPRING 扩展组件
    oracle 闪回
    ORACLE 日常
    springboot log4j
    支付宝异步回调验证签名的那些走过的坑
    ASP.NET MVC5(一)—— URL路由
  • 原文地址:https://www.cnblogs.com/SCL123/p/11831202.html
Copyright © 2011-2022 走看看