浅谈期望的线性性(可加性)

浅谈期望的线性性(可加性)

感性理解一下
E(X+Y)=E(X)+E(Y)
即两个(或多个)随机变量的和的期望等于期望的和

理论解释

如果不想看或者看不懂把规律记住

当然如果要理解透彻,那么就要练题

http://codeforces.com/problemset/problem/280/C

题目大意:

给定一棵有根树,每次随机选一个未被删除的点,将以它为根的子树删除。

求删除整棵树所用的期望步数。

solution:

初看每一个点被选它自己而被染色到的概率都是1/n

但仔细想想就会发现,某一个点对答案的贡献只与这个点有多少个祖先有关。

因为如果这个点会被选到,当且仅当它的所有祖先都没有被选到

所有每个点被选而被染色的概率为1/deep[i]。

期望的线性性

我们是不是可以计算出 每个点被染黑的期望操作次数,然后相加就是整棵树的了

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200003
using namespace std;
int n,tot,point[N],nxt[N],v[N],dep[N];
void add(int x,int y)
{
    tot++; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
    tot++; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void dfs(int x,int fa)
{
    dep[x]=dep[fa]+1;
    for (int i=point[x];i;i=nxt[i]){
        if (v[i]==fa) continue;
        dfs(v[i],x);
    }
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%d",&n);
    for (int i=1;i<n;i++) {
        int x,y; scanf("%d%d",&x,&y);
        add(x,y);
    }
    dfs(1,0);
    double ans=0;
    for (int i=1;i<=n;i++) 
     ans+=(double)(1.0/dep[i]);
    printf("%.9lf
",ans);
}

https://www.luogu.org/problem/P4316

Description
随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。
给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。
现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少?
Input
第一行: 两个整数 N M,代表图中有N个点、M条边
第二行到第 1+M 行: 每行3个整数 a b c,代表从a到b有一条长度为c的有向边
Output
从起点到终点路径总长度的期望值,四舍五入保留两位小数。
Sample Input
4 4
1 2 1
1 3 2
2 3 3
3 4 4
Sample Output
7.00
HINT
对于100%的数据 N<=100000,M<=2*N

由期望的线性性可得:

经过路径期望总长度=sigma{每条边期望经过次数*边权}

每条边的期望经过次数=该边起点的期望经过次数*从该起点出发经过该路径的概率

问题转成了求每个点的期望经过次数

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int N=100000+5;

int n,m,in[N],out[N];
int head[N],end[N*2],len[N*2],nxt[N*2],hh=0;
queue<int> q;
double p[N],ans=0;

void adde(int a,int b,int c){
    hh++;
    end[hh]=b;
    len[hh]=c;
    nxt[hh]=head[a];
    head[a]=hh;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        adde(a,b,c);
        in[b]++,out[a]++;
    }
    q.push(1);
    p[1]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            int v=end[i];
            ans+=p[u]/out[u]*len[i];
            p[v]+=p[u]/out[u];
            in[v]--;
            if(in[v]==0){
                q.push(v);
            }
        }
    }
    printf("%.2lf",ans);
    return 0;
}

再说一道睿(正)智(睿)今天考试题,作为T1哼哼,当然没A

分析:

对于ai=1的情况,很显然就是(1+2+3+.....+n)/n

考虑a11到n个不同的位置,其他的数有(n-1)!的排列,这样价值就是(1+2+3+4++++n)*(n-1)!

又因为有n!种排列所以就是(1+2+3+.....+n)/n

回到正题

code:

#include<bits/stdc++.h>
#define del(a,i) memset(a,i,sizeof(a))
#define ll long long
#define inl inline
#define il inl void
#define it inl int
#define ill inl ll
#define re register
#define ri re int
#define rl re ll
#define mid ((l+r)>>1)
#define lowbit(x) (x&(-x))
#define INF 0x3f3f3f3f
using namespace std;
template<class T>il read(T &x){
	int f=1;char k=getchar();x=0;
	for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
	for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
	x*=f;
}
template<class T>il _print(T x){
	if(x/10) _print(x/10);
	putchar(x%10+'0');
}
template<class T>il print(T x){
	if(x<0) putchar('-'),x=-x;
	_print(x);
}
ll mul(ll a,ll b,ll mod){long double c=1.;return (a*b-(ll)(c*a*b/mod)*mod)%mod;}
it qpow(int x,int m,int mod){
	int res=1,bas=x%mod;
	while(m){
		if(m&1) res=(1ll*res*bas)%mod;
		bas=(1ll*bas*bas)%mod,m>>=1;
	}
	return res%mod;
}
const int MAXN = 1e5+5;
int n,bas,val,mx;
double ans=1;
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	read(n);
	read(bas);
	for(ri i=2;i<=n;++i){
		read(val);
		ans+=val*1./(val+bas);
	}
	printf("%.10f",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/wzxbeliever/p/11679674.html