zoukankan      html  css  js  c++  java
  • HDU 4035 Maze 概率dp,树形dp 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=4035

    求步数期望,设E[i]为在编号为i的节点时还需要走的步数,father为dfs树中该节点的父节点,son为dfs树种该节点的子节点的集合,kl[i]为被杀掉的概率,ex[i]为逃出的概率

    mv[i]=(1-kl[i]-ex[i])/(1+len(son))

    则明显

    E[i]=(E[father]+1)*mv[i]+sigma((E[son]+1)*mv[i])+E[1]*K[i]

    未知量是E[i],E[father],E[1]

    对于叶节点,设E0[i]为该公式中E[1]的系数,EE[i]为该公式中的常数项,EF[i]为E[father]的系数,则可以用这三个值表示E[i]

    对于非叶节点,从E[son]中可以得到son的E0,EE,EF,另设ES[i]为E[i]在儿子中积累的系数,则

    EF[i]:mv[i]

    ES[i]:(由儿子积累来的)sigma(EF[son]*mv[i])

    EE[i]:1-kl[i]-ex[i]+sigma(EE[son]*mv[i])

    E0[i]:kl[i]+sigma(E0[son]*mv[i])

    计算完了之后再EE,E0,EF都除以(1-ES[i]),ES[i]为1当然就不能走出这个迷宫了

    这样到了1这个节点就是E[1]=EE[1]/(1-ES[1]-E0[1])

    一开始以为exit时应该有E[i]=ex[i]*E[i]+(E[father]+1)*mv[i]+sigma((E[son]+1)*mv[i])+E[1]*K[i],这里思想卡住了,实际上应该是ex[i]*0

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e4+4;
    const double eps = 1e-10;
    int n;
    double kl[maxn],ex[maxn],mv[maxn];//kill exit move
    int first[maxn],deg[maxn];
    int dcmp(double a,double b){
        if(fabs(a-b)<eps)return 0;
        return a>b?1:-1;
    }
    
    struct edge{
        int f,t,nxt;
    }e[maxn*2];
    void addedge(int f,int t,int ind){
        e[ind].nxt=first[f];
        e[ind].t=t;
        e[ind].f=f;
        first[f]=ind;
    }
    void input(){
        memset(first,-1,sizeof first);
        memset(deg,0,sizeof deg);
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int f,t;
            scanf("%d%d",&f,&t);
            addedge(f,t,2*i);
            addedge(t,f,2*i+1);
            deg[f]++;
            deg[t]++;
        }
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",kl+i,ex+i);
            kl[i]/=100;ex[i]/=100;
            if(deg[i])mv[i]=(1-ex[i]-kl[i])/deg[i];
        }
    }
    
    double ef[maxn],es[maxn],e0[maxn],ee[maxn];
    bool dfs(int s,int father){
        ef[s]=mv[s];
        //es[s]=ex[s];
        e0[s]=kl[s];
        ee[s]=1-kl[s]-ex[s];
        for(int p=first[s];p!=-1;p=e[p].nxt){
            int t=e[p].t;
            if(t==father)continue;
            if(!dfs(t,s))return false;
            es[s]+=ef[t]*mv[s];
            e0[s]+=e0[t]*mv[s];
            ee[s]+=ee[t]*mv[s];
        }
        if(dcmp(es[s],1)!=0&&s!=1){
            e0[s]/=(1-es[s]);
            ef[s]/=(1-es[s]);
            ee[s]/=(1-es[s]);
        }
        return true;
    }
    double calc(){
        memset(ee,0,sizeof ee);
        memset(ef,0,sizeof ef);
        memset(es,0,sizeof es);
        memset(e0,0,sizeof e0);
    
        if(!dfs(1,-1)||dcmp(e0[1]+es[1],1)==0)return -1;
        return ee[1]/(1-e0[1]-es[1]);
    }
    int main(){
        int T;
        scanf("%d",&T);
        for(int ti=1;ti<=T;ti++){
            input();
            double ans=calc();
            if(ans>-eps) printf("Case %d: %.6f
    ",ti,ans);
            else printf("Case %d: impossible
    ",ti);
        }
        return 0;
    }
    
  • 相关阅读:
    React组件化编程
    React入门
    typeof与instanceof比较+undefined与null各种值的相互比较
    JavaScript 数组去重
    JavaScript数组降维
    了解JS单线程和任务队列!
    clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop
    ES6—Set和Map
    数组+排序--知识点总结
    java scanner
  • 原文地址:https://www.cnblogs.com/xuesu/p/4484616.html
Copyright © 2011-2022 走看看