当前位置: 移动技术网 > IT编程>开发语言>C/C++ > HDU4035 Maze(期望DP)

HDU4035 Maze(期望DP)

2018年08月26日  | 移动技术网IT编程  | 我要评论

钓鱼太郎,P3预测霸王福彩4368,集成块

题意

抄袭自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\n", gg, c[1] / (1 - a[1]));
        else printf("case %d: impossible\n", gg);
    }
    return 0;
}
/*

*/

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网