• 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;
    }
    /*
    
    */
  • 相关阅读:
    Django DRF 分页
    django DRF理解
    Docker使用
    基于Django+FastDFS文件管理系统搭建
    django+centos+mariadb读写分离完美实现(上)-mysql主从备份实现
    Python协程理解——基于爬虫举例
    基于Python的大数据的分页模型代码
    NOIP模拟——矩阵分组
    NOIP模拟——聚会
    NOIP模拟——卡牌游戏
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9527740.html
Copyright © 2020-2023  润新知