zoukankan      html  css  js  c++  java
  • HDU4035 Maze(期望DP)

    题意

    抄袭自https://www.cnblogs.com/Paul-Guderian/p/7624039.html

    有n个房间,由n-1条隧道连通起来,形成一棵树,从结点1出发,开始走,在每个结点i都有3种可能(概率之和为1):1.被杀死,回到结点1处(概率为ki)2.找到出口,走出迷宫 (概率为ei)
    3.和该点相连有m条边,随机走一条求:走出迷宫所要走的边数的期望值。(2≤n≤10000)

    Sol

    非常nice的一道题。

    我简单的说一下思路:首先列出方程,$f[i]$表示在第$i$个位置走出迷宫的期望步数。

    转移方程分叶子节点和父亲节点讨论一下,发现都可以化成$f[x] = a f[1] + b f[fa] + c$的形式

    然后直接递推系数即可

    具体可以看https://www.cnblogs.com/Paul-Guderian/p/7624039.html

    /*
    
    */
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<vector>
    #include<set>
    #include<queue>
    #include<cmath>
    #define Pair pair<int, int>
    #define MP(x, y) make_pair(x, y)
    #define fi first
    #define se second
    //#define int long long 
    //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++)
    //char buf[(1 << 22)], *p1 = buf, *p2 = buf;
    using namespace std;
    const int MAXN = 1e5 + 10, INF = 1e9 + 10;
    const double eps = 1e-10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N;
    vector<int> v[MAXN];
    double b[MAXN], e[MAXN], A[MAXN], B[MAXN], C[MAXN];
    bool dcmp(double x) {
        if(fabs(x) < eps) return 0;
        else return 1;
    }
    void init() {
        for(int i = 1; i <= N; i++) v[i].clear();
    }
    double Get(int x) {
        return (1 - b[x] - e[x]) / (v[x].size());
    }
    bool dfs(int x, int fa) {
        if(v[x].size() == 1 && (v[x][0] == fa)) {A[x] = b[x], C[x] = B[x] = Get(x); return 1;}
        double As = 0, Bs = 0, Cs = 0;
        for(int i = 0; i < v[x].size(); i++) {
            int to = v[x][i];
            if(to == fa) continue;
            if(!dfs(to, x)) return 0;
            As += A[to]; Bs += B[to]; Cs += C[to] + 1;
        }
        double P = Get(x);
        double D = (1 - Bs * P);
        if(!dcmp(D)) return 0;
        A[x] = (b[x] + As * P) / D;
        B[x] = P / D;
        C[x] = (Cs * P + ((x == 1) ? 0 : P)) / D;
        return 1;
    }
    int main() {
        int T = read();
        for(int GG = 1; GG <= T; GG++) {
            N = read(); init();
            //printf("%d ", v[3].size());
            for(int i = 1; i <= N - 1; i++) {
                int x = read(), y = read();
                v[x].push_back(y); v[y].push_back(x);
            }
            for(int i = 1; i <= N; i++) b[i] = (double) read() / 100, e[i] = (double) read() / 100;
            if(dfs(1, 0) && (dcmp(1 - A[1]))) printf("Case %d: %.10lf
    ", GG, C[1] / (1 - A[1]));
            else printf("Case %d: impossible
    ", GG);
        }
        return 0;
    }
    /*
    
    */
  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9527740.html
Copyright © 2011-2022 走看看