1. 程式人生 > 實用技巧 >跳一跳 概率與期望

跳一跳 概率與期望

跳一跳 概率與期望

題目描述

現有一排方塊,依次編號為 \(1...n\)

方塊 \(1\) 上有一個小人,已知當小人在方塊 \(i\)上時,下一秒它會等概率地到方塊 \(i\)(即不動),方塊\(i+1\) ,方塊\(i+2\)$ …\(方塊\)n$ 上。

求小人到達方塊\(n\) 所需要的期望時間(單位:秒)。

輸入格式

一個數字\(n\)

輸出格式

若答案 \(ans=\frac{A}{B}\)輸出\(A \times 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] \times (n-i+1)=f[i]+f[i+1]+f[i+2]+...+f[n]+n-i+1\)

移項會有\(f[i] \times (n-i)= \sum_{j=i+1}^nf[j] + n-i+1\)

因此\(f[i]=(\sum_{j=i+1}^nf[j] + n-i+1) \times (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\n",ans);
    return 0;
}