• 跳一跳 概率与期望


    跳一跳 概率与期望

    题目描述

    现有一排方块,依次编号为 (1...n)

    方块 (1) 上有一个小人,已知当小人在方块 (i)上时,下一秒它会等概率地到方块 (i)(即不动),方块(i+1) ,方块(i+2)$ …(方块)n$ 上。

    求小人到达方块(n) 所需要的期望时间(单位:秒)。

    输入格式

    一个数字(n)

    输出格式

    若答案 (ans=frac{A}{B})输出(A imes B ^{-1} mod(10^9+7)) 。其中(B^{-1}) 表示(B mod (10^9+7)) 下的逆元。

    样例

    样例输入 1

    1
    

    样例输出 1

    0
    

    样例输入 2

    10000000
    

    样例输出 2

    406018741
    

    数据范围与提示

    对于(50\%) 的数据,(n leq 10^6)

    对于(100\%) 的数据,(1 leq n leq 10^7)

    分析

    我们设(f[i])为从位置(i)到达位置(n)的期望步数

    初始时有(f[n]=0)

    很显然(f[i]=(f[i]+f[i+1]+f[i+2]+...+f[n])/(n-i+1)+1)

    因为式子左右两边都含有(f[i]),因此我们需要将其消掉

    我们在式子左右两边同时乘上((n-i+1))

    那么会有 (f[i] imes (n-i+1)=f[i]+f[i+1]+f[i+2]+...+f[n]+n-i+1)

    移项会有(f[i] imes (n-i)= sum_{j=i+1}^nf[j] + n-i+1)

    因此(f[i]=(sum_{j=i+1}^nf[j] + n-i+1) imes (n-i)^{-1})

    转移时顺便记录一下后缀和

    因为这道题卡空间,所以(f)不能开数组,要用变量滚动

    代码

    #include<cstdio>
    const int maxn=1e7+5;
    const int mod=1e9+7;
    int ny[maxn],n,ans,sum;
    int main(){
        scanf("%d",&n);
        ny[1]=1;
        for(int i=2;i<=n;i++){
            ny[i]=1LL*(mod-mod/i)*ny[mod%i]%mod;
        }
        ans=0;
        for(int i=n-1;i>=1;i--){
            ans=1LL*(sum+n-i+1LL)*ny[n-i]%mod;
            sum=(sum+ans)%mod;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    1001. 害死人不偿命的(3n+1)猜想 (15)
    c语言学习习题
    设计模式随笔(四):单例模式
    设计模式随笔(三):建造者模式
    设计模式随笔(二):抽象工厂模式
    设计模式随笔(一):介绍java中常用的设计模式
    idea导入spring5.x源码编译
    使用idea从git上项目后jar包无法加载
    SFTP文件上传下载以及如何处理异常,页面展现
    Java代理模式
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13576548.html
Copyright © 2020-2023  润新知