zoukankan      html  css  js  c++  java
  • [概率与期望] Codeforces 1623D Robot Cleaner Revisit

    题目大意

    \(n\times m\) 的网格上有一个扫地机器人位于 \((x_1,y_1)\),有一个垃圾位于 \((x_2,y_2)\)。初始时速度为 \(dx=1,dy=1\) ,若机器人位于 \((x,y)\),则下一秒机器人将位于 \((x+dx,y+dy)\)。若机器人碰壁则速度方向变为反弹的方向。若机器人和垃圾位于同一行或同一列,有 \(p\%\) 的概率清理掉垃圾,有 \(1-p\%\) 的概率不清理。求扫地机器人清理掉垃圾的期望时间。\(n\cdot m\leq 10^5\)

    题解

    机器人的移动存在周期 \(C=\mathrm{lcm}(2(n-1),2(m-1))=\frac{2(n-1)(m-1)}{\gcd(n-1,m-1)}\)

    在一个周期内,设走了 \(i-1\) 步仍未清理掉垃圾的概率为 \(a_i\),走了 \(i\) 步才刚好清理掉垃圾的概率为 \(b_i\),则 \(a_i\)\(b_i\) 我们可以通过暴力一个周期算出。最后有:

    \[ans=\sum_{t=0}^\infty a_C^t\sum_{i=1}^C (i+tC)\times b_i\\ =\sum_{t=0}^\infty a_C^t\sum_{i=1}^C(ib_i+tCb_i)\\ =\left(\sum_{i=1}^C ib_i\right)\left(\sum_{t=0}^\infty a_C^t\right)+C\left(\sum_{i=1}^C b_i\right)\left(\sum_{t=0}^\infty ta_C^t\right)\\ =\left(\sum_{i=1}^C ib_i\right)\frac{1}{1-a_C}+C\left(\sum_{i=1}^C b_i\right)\frac{a_C}{(1-a_C)^2} \]

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define LL long long
    
    const LL MOD = 1e9 + 7;
    LL a[200010], b[200010], p;
    int T, n, m, X1, Y1, X2, Y2;
    
    LL qpow(LL b, LL n) {
        LL x = 1, Power = b % MOD;
        while (n) {
            if (n & 1) x = x * Power % MOD;
            Power = Power * Power % MOD;
            n >>= 1;
        }
        return x;
    }
    
    int main() {
        cin >> T;
        while (T--) {
            cin >> n >> m >> X1 >> Y1 >> X2 >> Y2 >> p;
            LL C = 2LL * (n - 1) / __gcd(n - 1, m - 1) * (m - 1);
            p = p * qpow(100, MOD - 2) % MOD;
            int dx = 1, dy = 1;
            a[0] = 1;
            LL sum_ib = 0, sum_b = 0;
            for (int i = 1;i <= C;++i) {
                LL sgn = (X1 == X2 || Y1 == Y2);
                a[i] = a[i - 1] * (1LL - sgn * p) % MOD;
                a[i] = (a[i] % MOD + MOD) % MOD;
                if (X1 + dx<1 || X1 + dx>n) dx *= -1;
                if (Y1 + dy<1 || Y1 + dy>m) dy *= -1;
                X1 += dx; Y1 += dy;
                if (X1 == X2 || Y1 == Y2) b[i] = a[i] * p % MOD;
                else b[i] = 0;
                sum_ib = (sum_ib + b[i] * i % MOD) % MOD;
                sum_b = (sum_b + b[i]) % MOD;
            }
            LL t = qpow((MOD + 1 - a[C]), MOD - 2);
            LL temp1 = sum_ib % MOD * t % MOD;
            LL temp2 = C * sum_b % MOD * a[C] % MOD * t % MOD * t % MOD;
            LL ans = (temp1 + temp2) % MOD;
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    关于jar项目发布(windows)
    SpringBoot 基础(一) mybatis 通过druid配置多数据库
    redis 基础(二) Redis安装
    测试开发3年,我决定去读个名校硕士
    大厂程序员凡尔赛的一天
    假如我拥有字节工牌。。。
    上海有哪些牛逼的互联网公司?
    那些学计算机的女生后来都怎么样了?
    微信支付零花钱刷屏了!5万额度,能花又能借
    清华集训 part1
  • 原文地址:https://www.cnblogs.com/AEMShana/p/15744577.html
Copyright © 2011-2022 走看看