淺談期望的線性性(可加性)


淺談期望的線性性(可加性)

感性理解一下
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\n",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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM