关于连续型随机变量的期望问题

定义

连续随机型变量的期望问题指的是:

对于一个连续型随机变量 \(X\) ,以及一个函数 \(f(x)=P[x==X]\) ,求 \(E(X)\) 的问题。

解法:

\(X\) 是一个离散型的随机变量,可能值为 \(x_1,x_2…\),对应的概率分别为 \(p_1,p_2…\),那么它的期望值就是 \(E(x)=∑_ip_ix_i\)

类似地,仍然考虑离散随机变量 \(X\) ,令它有 \(n\) 个取值 \(0,δ,2δ,3δ,…,(n−1)δ\) ,其中 \(δ\) 满足 \(δ=\frac{M}{n}\) ,且 \(M\) 为常数。那么它的期望就是:

\[\begin{aligned} E(x)=&\sum_{k=0}^{n-1}k\delta\times f(k\delta)=\sum_{k=0}^{n-1}k\delta\times P(X=k\delta)\\ =&\sum_{k=0}^{n-1}P(X=k\delta)\sum_{j=0}^{k-1}\delta\\ =&\sum_{j=0}^{n-1}\delta\sum_{k=j+1}^{n-1}P(X=k\delta)\\ =&\sum_{j=0}^{n-1}\delta \times P(j\delta<X) \end{aligned} \]

考虑 \(n→+∞\) 的时候,可以发现:

\[E(X)=\int_{0}^{M}\mathop{}\!\mathrm dt\times P(t< X) \]

由于 \(X\) 的取值被限制在 \([0,M)\) 里面,所以积分上界也可以被修改。

我们也可以通过几何意义来证明,期望相当于对所有等可能情况取平均值。

那么把 \(P(x<X)\) 的函数图像画出来,就是要求图像上每一点到 \(x\) 轴的距离的平均值,也就是函数面积除以以定义域大小。

#1178. 星际旅行

这题让我们求的是概率,因此我们只需要求 \(P(x==X)\) 图像上每一点到 \(x\) 轴的平均距离。

我们发现这个概率是一个分段函数,在一段区间 \([i,i+1)\) 中,一个物品被吸附的概率是一个特定的一次函数,我们只需像处理离散型随机变量时那样做背包,即可对每个 \(k\) 求出吸附 \(k\) 个物品的概率在这个区间内的函数。

对这个函数积分,转化原函数的面积公式:\(\int_{i}^{i+1}f(x)=\int_{0}^{i+1}f(x)-\int_{0}^{i}f(x)\),算出所有面积后除以定义域 \(L\) 即为平均高度。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,L;
int a[35],b[35];
using poly=vector<long double>;
inline poly operator +(poly a,poly b){
	if(a.size()<b.size())swap(a,b);
	for(int i=0;i<b.size();i++)a[i]+=b[i];
	return a;
}
inline poly operator -(int a,poly b){
	if(b.empty())b.resize(1);
	for(auto &it:b)it=-it;b[0]+=a;
	return b;
}
inline poly operator *(poly a,poly b){
	poly res(a.size()+b.size()-1);
	for(int i=0;i<a.size();i++){
		for(int j=0;j<b.size();j++)res[i+j]+=a[i]*b[j];
	}
	return res;
}
inline poly Integral(poly a){
	poly res(a.size()+1);
	for(int i=1;i<res.size();i++)res[i]=a[i-1]/i;
	return res;
}
inline long double Get(int x,poly f){
	long double res=0;
	for(int i=f.size()-1;~i;i--)res=res*x+f[i];
	return res;
}
poly dp[35];
long double ans[35];
int main(){
	scanf("%d%d",&n,&L);
	for(int i=1;i<=n;i++){
		int x;scanf("%d%d%d",&x,&a[i],&b[i]);
	}
	for(int t=0;t<L;t++){
		for(int i=0;i<=n;i++)dp[i].clear();
		dp[0]={1};
		for(int i=1;i<=n;i++){
			poly p;
			if(a[i]<=t&&t+1<=a[i]+b[i])p={1+1.0*a[i]/b[i],-1.0/b[i]};
			else if(a[i]-b[i]<=t&&t+1<=a[i])p={1-1.0*a[i]/b[i],1.0/b[i]};
			else continue;
			for(int j=n;j;j--)dp[j]=(1-p)*dp[j]+p*dp[j-1];
			dp[0]=dp[0]*(1-p);
		}
		for(int i=0;i<=n;i++)dp[i]=Integral(dp[i]);
		for(int i=0;i<=n;i++)ans[i]+=Get(t+1,dp[i])-Get(t,dp[i]);
	}
	long double E=0;
	for(int i=0;i<=n;i++)ans[i]/=L;
	for(int i=0;i<=n;i++)E+=i*ans[i];
	printf("%Lf\n",E);
	for(int i=0;i<=n;i++)printf("%Lf ",ans[i]);

	return 0;
}


ARC113F Social Distance

给一个长度为 \(n+1\) 的正整数序列 \(x\),保证 \(x_{0}=0\)\(x\) 递增。

现在随机生成一个长度为 \(n\) 的实数序列 \(y\),其中 \(y_{i}\)\(\left[x_{i-1}, x_{i}\right]\) 间随机生成。 定义序列 \(y\) 的权值为 \(\min _{i=1}^{n-1}\left(y_{i}-y_{i-1}\right)\),求 \(y\) 权值的期望,模 \(998244353\)

\(n \leq 20\)

\(4 s, 1024 \text{MB}\)

\(f(v)\) 表示权值大于等于 \(v\) 的概率,答案即为 \(\int_{v=0}^{+\infty} f(v) dv\)

考虑如何计算一个 \(f(v)\) ,问题相当于 \(y_{i}\)\(\left[x_{i-1}, x_{i}\right]\) 中随机生成,求 \(\forall i, y_{i}+v \leq y_{i+1}\) 的概率.考虑令 \(b_{i}=y_{i}-i * v\) ,则相当于 \(b_{i}\)\(\left[x_{i-1}-i v, x_{i}-i v\right]\) 中随机生成,求 \(\forall i, b_{i} \leq b_{i+1}\) 的概率。

考虑将概率乘上 \(\prod_{i}\left(x_{i}-x_{i-1}\right)\) ,这相当于将 \(b_{i}\)\(\left[x_{i-1}-i v, x_{i}-i v\right]\) 出现的概率分布都是 \(1\)

按照所有的区间端点将值域划分成 \(2 k\) 段,按照值从小到大排序,考虑枚举每个点的取值属于哪一段,则值所在的段编号一定不降。考虑一段内的情况,设一段长度为 \(l\) ,且有 \(k\) 个数取值在这一段内。可以考虑设 \(dp_{i, j, k}\) 表示考虑了前 \(i\) 个元素,当前第 \(i\) 个元素的值在第 \(j\) 段内,前面一共有 \(k\) 个元素在这一段内时,前面的所有情况贡献和。这样可以 \(O\left(n^{3}\right)\) 求出一个 \(f(v)\) ,这里还有很多不同的 \(dp\) 方式。

考虑 \(v\) 变化的情况,此时可以将所有边界看成关于 \(v\) 的一次函数,因此如果 \(v \in[l, r]\) 时,所有端点间的大小顺序不发生改变,则这一段内的 \(\mathrm{dp}\) 转移相同。在 \(\mathrm{dp}\) 时维护关于 \(v\) 的多项式,可以发现单次复杂度变为 \(O\left(n^{4}\right)\)

同时因为所有边界都是一次函数,可以发现大小顺序发生改变的次数为 \(O\left(n^{2}\right)\) ,因此对于每一段分别求贡献即可。

复杂度 \(O\left(n^{6}\right)\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
const int md=998244353;
inline int pwr(int x,int y){
	int res=1;
	while(y){
		if(y&1)res=1ll*res*x%md;
		x=1ll*x*x%md;y>>=1;
	}
	return res;
}
struct frac{
	int m,d;
	frac(int _m,int _d){
		m=_m;d=_d;
	}
	inline bool operator==(const frac &b)const{
		return m==b.m&&d==b.d;
	}
	inline bool operator<(const frac &b)const{
		return m*b.d<b.m*d;
	}
	inline operator int(){
		return 1ll*m*pwr(d,md-2)%md;
	}
};
struct point{
	int b,k,id;
	point(int _b,int _k,int _id){
		b=_b;k=_k;id=_id;
	}
	inline frac operator()(const frac &y)const{
		return frac(b*y.d-k*y.m,y.d);
	}
};
int x[25],w[55],inv[25],ifac[25];
inline void init(){
	inv[0]=inv[1]=ifac[0]=ifac[1]=1;
	for(int i=2;i<=n+1;i++)inv[i]=1ll*(md-md/i)*inv[md%i]%md;
	for(int i=2;i<=n+1;i++)ifac[i]=1ll*ifac[i-1]*inv[i]%md;
}
typedef vector<int> poly;
poly operator+(poly a,poly b){
    if(a.size()<b.size())swap(a,b);
    poly c=a;
    for(int i=0;i<b.size();i++)c[i]=(c[i]+b[i])%md;
    return c;
}
poly operator*(const poly& a,const poly& b){
    poly c(a.size()+b.size()-1);
    for(int i=0;i<a.size();i++)
        for(int j=0;j<b.size();j++)c[i+j]=(c[i+j]+1ll*a[i]*b[j]%md)%md;
    return c;
}
poly operator*(const poly& a,int b){
    poly c(a.size());
    for(int i=0;i<a.size();i++)c[i]=1ll*a[i]*b%md;
    return c;
}
poly integral(const poly& a){
    poly c(a.size()+1);
    for(int i=1;i<c.size();i++)c[i]=1ll*a[i-1]*inv[i]%md;
    return c;
}
int getval(const poly& a,int x){
    int x2=1,res=0;
    for(int i=0;i<a.size();i++)res=(res+1ll*a[i]*x2%md)%md,x2=1ll*x2*x%md;
    return res;
}
poly f[55][25];
int main(){
    scanf("%d",&n);init();
    for(int i=0;i<=n;i++)scanf("%d",&x[i]);
    vector<point>p;
    for(int i=1;i<=n;i++)p.emplace_back(x[i-1],i-1,2*i-1),p.emplace_back(x[i],i-1,2*i);
    vector<frac>t;
    for(int i=0;i<2*n;i++)
        for(int j=i+2-(i & 1);j<2*n;j++)t.emplace_back(p[j].b-p[i].b,p[j].k-p[i].k);
    sort(t.begin(),t.end()),t.erase(unique(t.begin(),t.end()),t.end());
    int ans=0;
    for(int nt=0;nt<t.size()-1;nt++){
        auto cmp=[&](const point& a,const point& b){
            if(a(t[nt])==b(t[nt]))return a.k>b.k;
            return a(t[nt])<b(t[nt]);
        };
        sort(p.begin(),p.end(),cmp);
        for(int i=0;i<p.size();i++)w[p[i].id]=i;
        f[0][0]={1};
        for(int i=1;i<p.size();i++){
            for(int j=0;j<=n;j++){
                f[i][j].clear();
                poly z={(p[i].b-p[i-1].b+md)%md,(p[i-1].k-p[i].k+md)%md},z2=z;
                for(int k=1;k<=j;k++){
                    int nid=j-k+1,L=w[2*nid-1],R=w[2*nid]-1;
                    if(L>i-1||i-1>R)break;
                    f[i][j]=f[i][j]+f[i-1][nid-1]*z*ifac[k];
                    z=z*z2;
                }
                f[i][j]=f[i][j]+f[i-1][j];
            }
        }
        poly g=integral(f[p.size()-1][n]);
        ans=(ans+(getval(g,t[nt+1])-getval(g,t[nt])+md)%md)%md;
    }
    for(int i=1;i<=n;i++)ans=1ll*ans*pwr(x[i]-x[i-1],md-2)%md;
    printf("%d",ans);


	return 0;
}

posted @ 2022-07-26 22:06  一粒夸克  阅读(2882)  评论(0编辑  收藏  举报