• 【题解】CF#24 D-Broken Robots


      在某次考试的时候用过的办法,懒人必备……【笑哭】

      一个非常显然的 dp,我们用 (f[i][j]) 表示第 (i) 行第 (j) 列的格子走到最后一排的期望步数转移即为

    (f[i][j] = frac{f[i][j - 1] + f[i][j + 1] + f[i + 1][j] + f[i][j]}{4} + 1)

    略微的化一下简:

    (f[i][j] = frac{f[i][j - 1] + f[i][j + 1] + f[i + 1][j] + 4}{3})

      (当然,对于 j = 1 和 j = m 的情况是另外两个式子,但推导的方法是一样的)。这个式子使用高斯消元优化一下就能搞定,然而非常悲伤,像我这样的蒟蒻写高斯消元常常写挂,也不是很敢码。那怎么办办呢?人工大法好啊!

      我们可以注意到行与行之间是不会相互转移的,我们可以认为当前行的 dp 数组为 f,下一行的 dp 数组为 g。那么对于 (f[i][m]) 而言,我们有

    (f[m] = frac{f[m - 1] + g[m] + 3}{2})

    也就是说,我们可以用 (f[i - 1]) 来表示出 (f[i]) 的值!

    那么每从 (f[j] -> f[j - 1]),我们都可以得到一个递推式

    (f]j] = k * f[j - 1] + t)

    那么这个式子递归到尽头 f[1] 的时候

    我们陡然发现式子中的未知数只剩下了一个 f[1]!

    此时,只需不断回代就能得到 f[2 ... m]。

      复杂度 (O(n * m)) ,非常优秀是吧~

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 1050
    #define db double
    int n, m, S, T;
    db f[maxn][maxn];
    
    int read()
    {
        int x = 0, k = 1;
        char c; c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    void DP(int p, int x, db k, db t)
    {
        if(!x) return;
        if(x == 1)
        {
            f[p][x] = (f[p + 1][x] + 3.0 + t) / (2.0 - k);
            return;
        }
        db k1 = 1 / (3.0 - k), t1 = (f[p + 1][x] + 4.0 + t) / (3.0 - k);
        DP(p, x - 1, k1, t1); 
        f[p][x] = f[p][x - 1] * k1 + t1;
    }
    
    int main()
    {
        n = read(), m = read(), S = read(), T = read();
        for(int i = n - 1; i >= 1; i --)
        {
            db k = 0.5, t = 0.5 * (3.0 + f[i + 1][m]);
            DP(i, m - 1, k, t);
            if(m == 1) f[i][m] = f[i + 1][m] + 2.0;
            else f[i][m] = k * f[i][m - 1] + t;
        }
        printf("%.10lf
    ", f[S][T]);
        return 0;
    }
  • 相关阅读:
    C++异常第二篇---C++标准库异常类exception的使用
    C++异常(exception)第一篇--综合讲解
    libconfig第二篇----两个小例子
    libconfig第一篇———使用指南
    log4cxx第三篇----使用多个logger
    kafka第五篇
    kafka第四篇--快速入门(如何使用kafka)
    UVA 455(最小周期)
    UVA1584(环状序列)
    UVA1583(最小生成元)
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/9909899.html
Copyright © 2020-2023  润新知