洛谷-5147 随机数生成器

该博客主要讨论了HKE编写的rand函数以及在此基础上的work函数,工作函数的期望值问题。通过给出的输入输出样例,博主解释了如何推导出期望值公式,并展示了解决此问题的思路,特别是对于n值较大时的近似计算方法,涉及到数学中的等比数列和自然对数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
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) 返回的所有可能的值为 x1,x2,…,xkx_1,x_2,\dots ,x_kx1,x2,,xk,它们出现的概率分别为 p1,p2,…,pkp_1,p_2,\dots,p_kp1,p2,,pk,则期望为:
E=∑i=1npixiE=\sum\limits_{i=1}^np_ix_iE=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=1n1nE(i)+1E(n)=\sum\limits_{i=1}^n\frac{1}{n}E(i)+1E(n)=i=1nn1E(i)+1
nE(n)=∑i=1nE(i)+nnE(n)=\sum\limits_{i=1}^nE(i)+nnE(n)=i=1nE(i)+n另外
(n−1)E(n)=∑i=1n−1E(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)=1n−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=3n−1D(n)E(n)=E(2)+\sum\limits_{i=3}^{n-1}D(n)E(n)=E(2)+i=3n1D(n)
=2+∑i=1n−11i=2+\sum\limits_{i=1}^{n-1}\frac{1}{i}=2+i=1n1i1
其中n=1和n=2要特判断
又当n足够大的时候,
∑i=1n1i=ln⁡(n)+γ\sum\limits_{i=1}^n\frac{1}{i}=\ln(n)+\gammai=1ni1=ln(n)+γ
γ=0.5772156649015328...\gamma=0.5772156649015328...γ=0.5772156649015328...
完成

#include <iostream>
#include<cstdio>
#include<cmath>
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值