1 条题解

  • 0
    @ 2025-11-10 22:52:18

    方块移动期望时间问题解析

    问题分析

    题目描述:一排编号为1到n的方块,小人从方块1出发,移动规则为:当在方块i上时,下一秒会等概率移动到方块i、i+1、……、n中的任意一个。求到达方块n的期望时间(单位:秒),结果以分数A/B的形式表示为A×B⁻¹ mod (10⁹+7)。

    递推公式推导

    设E[i]为从方块i到达方块n的期望时间。显然,E[n] = 0(已到达目标)。

    对于i < n时,分析移动规则:

    • 从方块i出发,可移动到i、i+1、……、n,共k = n - i + 1个位置
    • 每个位置的概率为1/k
    • 期望时间满足:E[i] = 1 + (E[i] + E[i+1] + ... + E[n])/k(1秒为当前步,加上后续期望的平均值)

    整理方程: 两边乘以k得:k·E[i] = k + E[i] + E[i+1] + ... + E[n] 移项化简:(k-1)·E[i] = k + (E[i+1] + ... + E[n]) 其中k = n - i + 1,故k-1 = n - i,代入得: E[i] = [ (n - i + 1) + (E[i+1] + ... + E[n]) ] / (n - i)

    优化计算与递推

    直接计算E[i]需累加E[i+1]到E[n],时间复杂度会达O(n²),不适合n=1e7的规模。引入辅助变量S[i] = E[i] + E[i+1] + ... + E[n](从i到n的期望和),则:

    • S[i] = E[i] + S[i+1]
    • E[i]的表达式可改写为:E[i] = [ (n - i + 1) + S[i+1] ] / (n - i)

    利用S[i]的递推关系,可将计算优化为O(n):

    • 从i = n-1逆推至i = 1(因E[n] = 0,S[n] = 0)
    • 每次计算E[i]时,S[i+1]已通过之前的结果累加得到

    模运算与逆元处理

    结果需以A×B⁻¹ mod (10⁹+7)表示,其中B⁻¹是B在模10⁹+7下的乘法逆元。由于计算E[i]时涉及除法(除以n-i),需用逆元替代:

    • 逆元计算采用线性递推公式:inv[1] = 1;对于i > 1,inv[i] = MOD - MOD/i × inv[MOD%i] % MOD(MOD=1e9+7)
    • 该方法可在O(n)时间内预处理1到n的所有逆元

    代码解析

    #include <iostream>
    using namespace std;
    typedef long long ll;
    ll n;
    ll ans;
    const ll MOD = 1e9 + 7, MAXN = 1e7;
    ll dp = 0, s = 0;  // dp表示E[i],s表示S[i+1](E[i+1]到E[n]的和)
    int inv[MAXN + 10];  // 逆元数组
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n;
        if (n == 1) {  // 特殊情况:已在目标位置
            cout << 0;
            return 0;
        }
        // 预处理逆元
        inv[1] = 1;
        for (int i = 2; i <= n; i++)
            inv[i] = MOD - MOD / i * inv[MOD % i] % MOD;
        
        // 从i = n-1逆推到i = 1
        for (ll i = n - 1; i > 0; i--) {
            s = (s + dp) % MOD;  // 更新S[i+1](累加E[i+1])
            ll k_minus_1 = n - i;  // k-1 = n - i
            ll numerator = (s + (n - i + 1)) % MOD;  // 分子:(n-i+1) + S[i+1]
            dp = numerator * inv[k_minus_1] % MOD;  // E[i] = 分子 / (n-i) = 分子 × 逆元
        }
        
        cout << dp;  // dp最终为E[1]
    }
    

    时间复杂度分析

    • 逆元预处理:O(n)
    • 递推计算E[i]:O(n)
    • 总时间复杂度:O(n),可高效处理n=1e7的规模。
    • 1

    信息

    ID
    4724
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者