概率初步笔记

1.样本空间 Ω 代表事件的全集,即一次实验发生的所有事件的并集。
2.概率测度 P(A) 表示 A 事件在样本空间中的发生概率(跟没有解释一样 = =)。
3.概率测度满足一些性质:
AΩP(A)=1
AΩ,P(A)>=0
AB=,P(AB)=P(A)+P(B)
4.全概率公式:
如果 Bi 是样本空间的一个划分,那么
P(A)=kP(A|Bk)P(Bk)


例子:
一座学校里,有OI班和普通班。
OI班有 a 个,普通班有b个。
这样OI班和普通班就把整个学校里的班级划分成了两个部分。
每个OI班里有 c 个男生和d个女生,其中 c>0,d=0 .
每个普通班里有 e 个男生和f个女生,其中 e>0,f>0 .
(一本正经)
现在随机挑一个学生,问是妹子的概率?
A 表示随便挑个学生,是妹子的这个事件。
B1表示随便挑个学生,跑到OI班的概率。
B2 表示随便挑个学生,跑到普通班的概率。
P(A)=P(A|B1)P(B1)+P(A|B2)P(B2)
这样就直观地表示了全概率公式。


5.贝叶斯公式:

P(A|B)=P(A)P(B|A)P(B)

这个公式就是逗你玩的,推导过程的话其实是 P(AB)=P(A)P(B|A) .
注意, A B事件可以是独立的。
这个公式在计算 逆向概率很有用。
6.随机变量:
随机变量 X 它是个函数
它是定义在样本空间的一个函数(实数)。
比如:X(ω)就表示发生了事件 ω 时,这个函数的值。
7.随机变量的期望:
E[X]=ωΩP(ω)X(ω)=xxP(X=x)

其中 X=x 的意思是,随机变量的值为 x 的事件(集合)。
太抽象了,举个例子:
实验是从刚刚那个学校里抽一个学生。
样本空间是所有学生组成的集合。
随机变量X是抽出来的那个学生的性别。
其实当X 1 的时候,自变量可能有很多个。
E[X]=x1P(X=1)

8.期望的线性性:
X,Y 为两个随机变量:
E[aX+bY]=aE[X]+bE[Y]

9.全期望公式:
设有两个随机变量 X,Y .
定义 g(y)=E[X|Y=y]
那么有 E[g(y)]=E[x]
合起来写的话 E[E[X|Y]]=E[X]
10.概率转移网络:
一个带起点的有向网络,在 u 上的点有G[u,v]的概率转移到 v 1vVG[u,v]的概率直接消失掉。这个东西是可以解方程算的。
似乎期望题都要倒着推……并不知道为什么……
SDOI2012是一个高斯消元的题目, 我现在才知道期望可以消…….

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
#define v edge[i].to
#define Dwn(i,n) for(int i = n;i;i --)
using namespace std;
const int N = 20005;
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
int stk[N],tp,low[N],dfn[N],bel[N],scc,n,m,S,T,vis[N],ran[N],d[N],head[N],cnt,tim;
double f[N],a[105][105],ans[105];
vector<int>vec[N];
const double eps = 1e-7;
bool sgn(double t){return fabs(t) > eps;}
struct Edge{int next,to;}edge[N*100];
void save(int a,int b){edge[cnt] = (Edge){head[a],b},head[a] = cnt ++;d[a] ++;}
void dfs(int x)
{
    low[stk[++ tp] = x] = dfn[x] = ++ tim;
    RepG(i,x)
        if(!dfn[v])dfs(v),low[x] = min(low[v],low[x]);
        else if(!bel[v])low[x] = min(low[x],dfn[v]);
    if(low[x] == dfn[x])
    {
        int y,lst = 0;++ scc;
        do{bel[y = stk[tp --]] = scc;vec[scc].push_back(y);ran[y] = ++ lst;}while(y != x);
    }
}
void Gauss(int nn)
{
    double x;int j;
    Rep(i,nn)
    {
        for(j = i;j <= nn;++ j)if(sgn(a[j][i]))break;
        if(j > nn)continue;
        if(i != j)Rep(k,nn + 1)swap(a[i][k],a[j][k]);
        for(j = i + 1;j <= nn;++ j)
        {
            x = a[j][i] / a[i][i];
            if(!sgn(x))continue;
            for(int k = i;k <= nn + 1;++ k)a[j][k] -= a[i][k] * x;
        }
    }
    memset(ans,0,sizeof(ans));
    Dwn(i,nn)
    {
        ans[i] = a[i][nn + 1];
        if(fabs(a[i][i]) < eps)
        {
            printf("INF\n");
            exit(0);
        }
        for(int j = i + 1;j <= nn;++ j)ans[i] -= a[i][j] * ans[j];
        ans[i] /= a[i][i];
    }
}
void dfs2(int y)
{
    vis[y] = -1;
    if(y == bel[T]){vis[y] = 1;return;}
    for(int j = 0;j < vec[y].size();++ j)
    {
        int x = vec[y][j];
        RepG(i,x)
        {
            if(bel[v] == y)continue;
            if(!vis[bel[v]])dfs2(bel[v]);
            if(vis[bel[v]] == 1)vis[y] = 1;
        }
    }
}
void solve(int xx)
{
    int nn = vec[xx].size();
    for(int yy = 0;yy < nn;++ yy)
    {
        int x = vec[xx][yy];
        RepG(i,x)if(bel[v] != xx && !vis[bel[v]])solve(bel[v]);
    }
    memset(a,0,sizeof(a));
    for(int i = 1;i <= nn;++ i)
    {
        a[i][i] = 1;
        if(vec[xx][i - 1] == T)continue;
        a[i][nn + 1] = 1;
        int x = vec[xx][i - 1];
        RepG(j,x)
        {
            int vv = edge[j].to;
            if(bel[vv] == xx)a[i][ran[vv]] -= 1.0 / d[x];
            else a[i][nn + 1] += 1.0 / d[x] * f[vv];
        }
    }
    Gauss(nn);
    Rep(i,nn)f[vec[xx][i - 1]] = ans[i];
    vis[xx] = 1;
}
int main ()
{
    scanf("%d%d%d%d",&n,&m,&S,&T);
    memset(head,-1,sizeof(head));
    Rep(i,m){int A,B;A = read(),B = read(),save(A,B);}
    Rep(i,n)if(!dfn[i])dfs(i);
    memset(vis,0,sizeof(vis));
    dfs2(bel[S]);
    Rep(i,scc)if(vis[i] < 0)return puts("INF"),0;
    memset(vis,0,sizeof(vis));
    solve(bel[S]);
    printf("%.3f\n",f[S]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值