洛谷-5147 随机数生成器

题目描述
HKE最近编写了一个函数 rand \text{rand} rand,其中 l,r 为正整数且 l≤r。这个函数会等概率返回区间 [l,r] 中任意一个正整数。然后,他又编写了一个函数:
int work(int x){
if(x==1) return 0;
else return work(rand(1,x))+1;
}
现在给定一个正整数 n,请问 work(n) 的返回值的期望值是多少?
期望的定义:假设 work(n) 返回的所有可能的值为 x 1 , x 2 , … , x k x_1,x_2,\dots ,x_k x1,x2,,xk,它们出现的概率分别为 p 1 , p 2 , … , p k p_1,p_2,\dots,p_k p1,p2,,pk,则期望为:
E = ∑ i = 1 n p i x i E=\sum\limits_{i=1}^np_ix_i E=i=1npixi

输入格式
一个正整数 n

输出格式
一个实数,表示 work(n) 的期望值。保留 5 位小数。

输入输出样例
输入 #1
2

输出 #1
2.00000

输入 #2
3

输出 #2
2.50000

输入 #3
100000

输出 #3
13.09014

说明/提示
对于 100% 的数据,1≤n<231

解释:推公式额。
E ( n ) = ∑ i = 1 n 1 n E ( i ) + 1 E(n)=\sum\limits_{i=1}^n\frac{1}{n}E(i)+1 E(n)=i=1nn1E(i)+1
n E ( n ) = ∑ i = 1 n E ( i ) + n nE(n)=\sum\limits_{i=1}^nE(i)+n nE(n)=i=1nE(i)+n另外
( n − 1 ) E ( n ) = ∑ i = 1 n − 1 E ( i ) + n − 1 (n-1)E(n)=\sum\limits_{i=1}^{n-1}E(i)+n-1 (n1)E(n)=i=1n1E(i)+n1
两式相减得
( n − 1 ) ( E ( n ) − E ( n − 1 ) ) = 1 (n-1)(E(n)-E(n-1))=1 (n1)(E(n)E(n1))=1
E ( n ) − E ( n − 1 ) = 1 n − 1 = D ( n ) E(n)-E(n-1)=\frac{1}{n-1}=D(n) E(n)E(n1)=n11=D(n)
E ( n ) = E ( 2 ) + ∑ i = 3 n − 1 D ( n ) E(n)=E(2)+\sum\limits_{i=3}^{n-1}D(n) E(n)=E(2)+i=3n1D(n)
= 2 + ∑ i = 1 n − 1 1 i =2+\sum\limits_{i=1}^{n-1}\frac{1}{i} =2+i=1n1i1
其中n=1和n=2要特判断
又当n足够大的时候,
∑ i = 1 n 1 i = ln ⁡ ( n ) + γ \sum\limits_{i=1}^n\frac{1}{i}=\ln(n)+\gamma i=1ni1=ln(n)+γ
γ = 0.5772156649015328... \gamma=0.5772156649015328... γ=0.5772156649015328...
完成

#include 
#include
#include
using namespace std;
const int limit = 19260817;
const double _gamma = 0.5772156649015328;
double ans=0;
int main(){
    int n=0;cin>>n;
    if(n==1) ans=0.0;
    else if(n==2) ans=2.0;
    else if(n<=limit){
        ans=2.0;
        for(int i=3;i<=n;i++) ans+=1.0/(i-1);
    }else{
        ans=log(n)+_gamma+1;
    }
    printf("%.5f\n",ans);
    return 0;
}

你可能感兴趣的:(算法题)