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;
    }
    
  • 相关阅读:
    HDU 6071
    HDU 6073
    HDU 2124 Repair the Wall(贪心)
    HDU 2037 今年暑假不AC(贪心)
    HDU 1257 最少拦截系统(贪心)
    HDU 1789 Doing Homework again(贪心)
    HDU 1009 FatMouse' Trade(贪心)
    HDU 2216 Game III(BFS)
    HDU 1509 Windows Message Queue(队列)
    HDU 1081 To The Max(动态规划)
  • 原文地址:https://www.cnblogs.com/xuesu/p/4484616.html
Copyright © 2011-2022 走看看