站外题求助
  • 板块灌水区
  • 楼主无名之雾
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/12/17 13:10
  • 上次更新2023/12/17 13:30:02
查看原帖
站外题求助
704275
无名之雾楼主2023/12/17 13:10

时间限制: 1.0 秒

空间限制: 512 MiB

题目描述

小兰很喜欢随机数。 TA 首先选定了一个实数 0<p<1,然后生成了 n 个随机数 x1,…,xn,每个数是独立按照如下方式生成的:

x i有 p 的概率是 1有 (1−p)p 的概率是 2,有 (1−p) ^2*p 的概率是 3 以此类推。

生成完这些随机数之后,小艾对这个数列求了前缀和,得到了数列 y 1,…,y n 。

给定 1≤l≤r≤n,小兰想知道,期望有多少 y i落在 [l,r] 内?

输入格式

从标准输入读入数据。

一行输入四个数

n,p,l,r。保证

1≤l≤r≤n≤10 ^9,

p 的位数不超过 6。

输出格式

输出到标准输出。

输出一个实数,表示答案。你需要保证答案的绝对或相对误差不超过 10^−6

样例1输入

3 0.5 1 2

样例1输出

1.000000

我的代码

#include<bits/stdc++.h>
using namespace std;
double pre(int n,double p,int l,int r) {
    vector<double>dp(n+1,0.0);
    vector<double>cum(n+1,0.0);
    dp[1]=p;
    cum[1]=p;
    for (int i=2;i<n;i++) {
        dp[i]=(1-p)*dp[i-1];
        cum[i]=cum[i-1]+dp[i];
    }
    double ex=cum[r]-cum[l-1];
    if(l>1)ex+=cum[l-1];
    return ex;
}
int main(){
    int n, l, r;
    double p;
    cin>>n>>p>>l>>r;
    double result = pre(n, p, l, r);
    cout.setf(ios::fixed);
    cout.precision(6);
    cout<<result;
    return 0;
}

我的思路

首先,我们可以通过动态规划的方法计算每个前缀和的概率,并将其保存在一个数组中。设 dp[i] 表示前缀和为 i 的概率。

对于第一个随机数,有 dp[1] = p、dp[2] = (1-p)p、dp[3] = (1-p)^2p,以此类推。

然后,我们可以计算累积概率数组 cumProb[i],表示前缀和小于等于 i 的概率。

累积概率数组的计算公式为 cumProb[i] = cumProb[i-1] + dp[i]。

接下来,我们可以通过 cumProb 数组计算指定区间 [l, r] 的前缀和的期望。

期望的计算公式为 E = cumProb[r] - cumProb[l-1]。

最后,将得到的期望输出即可。

2023/12/17 13:10
加载中...