zoukankan      html  css  js  c++  java
  • luoguP4206 [NOI2005]聪聪与可可 期望概率DP

    首先,分析一下这个猫和鼠

    猫每局都可以追老鼠一步或者两步,但是除了最后的一步,肯定走两步快些....

    既然猫走的步数总是比老鼠多,那么它们的距离在逐渐缩小(如果这题只能走一步反而不能做了...)

    猫不知道老鼠下一步走哪里,猫走的时候依据的是老鼠当前的位置

    明显,猫走的位置没有什么规律可言(即使有规律还是会预处理啊.....)

    我们可以在$O(n^2 + nm)$的复杂度内预处理出$s(i, j)$表示猫在$i$,老鼠在$j$时,猫下一步的位置...

    直接设$f(i, j)$表示猫在$i$,老鼠在$j$时猫吃到老鼠的期望步数

    那么有$f(i, i) = 0$

    并且$f(i, s(i, j)) = 1,f(i, s(s(i, j), j)) = 1 (i eq j)$

    其余情况下$f(i, j) = sumlimits_{v = j | e(j, v)} frac{f(s(s(i, j), j), v) + 1}{du[j] + 1}$

    由于猫鼠距离减小,因此转移具有拓扑序

    可以根据猫鼠距离排序转移,也可以直接$dfs$

    由于$dfs$好写,因此这里选择$dfs$

    复杂度$O(n^2 + nm)$

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    
    #define de double
    #define sid 1005
    #define eid 5005
    #define ri register int
    
    int n, m, s, t, cnp;
    int cap[eid], nxt[eid], node[eid], q[eid];
    int du[sid], dis[sid][sid], nx[sid][sid];
    de f[sid][sid];
    
    void adeg(int u, int v) {
        du[u] ++;
        nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
    }
    
    #define cur node[i]
    void Pre() {
        for(ri u = 1; u <= n; u ++) {
            int fr = 1, to = 0;
            q[++ to] = u; dis[u][u] = 0;
            while(fr <= to) {
                int o = q[fr ++];
                for(ri i = cap[o]; i; i = nxt[i])
                if(dis[u][cur] == 1e5)
                dis[u][cur] = dis[u][o] + 1, q[++ to] = cur;
            }
        }
        for(ri u = 1; u <= n; u ++)
        for(ri v = 1; v <= n; v ++) {
            int w = 1e5;
            for(ri i = cap[u]; i; i = nxt[i])
            if(dis[cur][v] < w || (dis[cur][v] == w && nx[u][v] > cur))
            nx[u][v] = cur, w = dis[cur][v];
        }
    }
    
    de dfs(int a, int b) {
        if(f[a][b] != -1) return f[a][b];
        if(a == b) return f[a][b] = 0;
        int to = nx[a][b], toto = nx[to][b];
        if(to == b || toto == b) return f[a][b] = 1;
        f[a][b] = 0;
        for(int i = cap[b]; i; i = nxt[i])
        f[a][b] += (dfs(toto, cur) + 1) / (de)(du[b] + 1);
        f[a][b] += (dfs(toto, b) + 1) / (de)(du[b] + 1);
        return f[a][b];
    }
    
    int main() {
        n = read(); m = read();
        s = read(); t = read();
        for(ri i = 1; i <= m; i ++) {
            int u = read(), v = read();
            adeg(u, v); adeg(v, u);
        }
    
        for(ri i = 1; i <= n; i ++)
        for(ri j = 1; j <= n; j ++)
        dis[i][j] = 1e5, f[i][j] = -1;
    
        Pre();
        printf("%.3lf
    ", dfs(s, t));
        return 0;
    }
  • 相关阅读:
    windows server 2008 r2安装windows media player
    IE打开https网站时,取消证书问题提示
    取消IE、Office、Wmp首次开启提示
    testNG安装一直失败解决方法
    Jmeter接口测试问题及解决方法积累
    大数据:实时技术
    大数据:离线数据开发
    大数据:数据同步
    大数据:日志采集
    大数据:Hadoop(HDFS 读写数据流程及优缺点)
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9513915.html
Copyright © 2011-2022 走看看