概率&期望
【概率】
%%%无意中找到一位大佬的博客讲三条概率公式,讲得极好,戳这里
公式
1、条件概率公式
2、全概率公式
3、贝叶斯公式
【期望】
公式
离散型随机变量X的取值为
,
为X对应取值的概率,可理解为数据
出现的频率
,则:

栗1(高斯消元系列)(题目戳这里)
题意:一个人在数轴上来回走,以pi的概率走i步i∈[1, m],给定n(数轴长度),m,e(终点),s(起点),d(方向),求从s走到e经过的点数期望。
CODE:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <cmath> using namespace std; const int MLn = 220; const double eps = 1e-8; int n, m, s, e, tmp, N; double p[MLn], a[MLn][MLn], x[MLn]; queue <int> q; int num[MLn], cnt = 0; bool Gauss() { for (int i=0; i<cnt; i++) { int id = i; for (int j=i+1; j<cnt; j++) if(fabs(a[id][i]) < fabs(a[j][i])) id = j; if(fabs(a[id][i]) < eps) return false; if(i != id) for (int j=0; j<cnt; j++) swap(a[i][j], a[id][j]); swap(x[id], x[i]); for (int j=0; j<cnt; j++) { if(j == i || !a[j][i]) continue; double te = a[j][i] / a[i][i]; x[j] -= x[i] * te; for (int k=i; k<cnt; k++) a[j][k] -= a[i][k]*te; } } return true; } void bfs() { while(!q.empty()) q.pop(); memset(num, -1, sizeof(num)); num[s] = cnt++, q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); for (int i=1; i<=m; i++) { int t = (i+u) % N; if(fabs(p[i]) < eps || num[t]!=-1) continue; num[t] = cnt++, q.push(t); } } } int main() { int T; scanf("%d", &T); while(T--) { cnt = 0; scanf("%d%d%d%d%d", &n, &m, &e, &s, &tmp); for (int i=1; i<=m; i++) scanf("%lf", &p[i]), p[i]/=100; if(e == s) { printf("0.00\n"); continue; } N = 2 * (n-1); if(tmp == 1) s = N-s; bfs(); if(num[e]==-1 && num[N-e]==-1) { printf("Impossible !\n"); continue; } memset(a, 0, sizeof(a)); memset(x, 0, sizeof(x)); for (int i=0; i<N; i++) { if(num[i]==-1) continue; if(i == e || i == N-e) { a[num[i]][num[i]] = 1, x[num[i]] = 0; continue; } a[num[i]][num[i]] = 1; for (int j=1; j<=m; j++) { int t = (i+j) % N; if(num[t]==-1) continue; a[num[i]][num[t]] -= p[j], x[num[i]] += j * p[j]; } } if(Gauss()) printf("%.2lf\n", x[num[s]]/a[num[s]][num[s]]); else printf("Impossible !\n"); } return 0; }
栗2(题目戳这里)
CODE:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; double p[22]; int main() { int n; while(~scanf("%d",&n)) { for(int i=0;i<n;i++)scanf("%lf",&p[i]); double ans=0; for (int i=1; i<(1<<n); i++) { int cnt = 0; double sum = 0; for (int j=0; j<n; j++) if(i&(1<<j)) { sum+=p[j]; cnt++; } if(cnt&1) ans += 1.0/sum; else ans -= 1.0/sum; } printf("%.4lf\n",ans); } return 0; }
练习
hdu 4418 http://acm.hdu.edu.cn/showproblem.php?pid=4418
hdu 4336 http://acm.hdu.edu.cn/showproblem.php?pid=4336
https://www.luogu.org/problemnew/show/P3412
https://www.luogu.org/problemnew/show/P1297
https://www.lydsy.com/JudgeOnline/problem.php?id=3566
https://www.lydsy.com/JudgeOnline/problem.php?id=1415
https://www.lydsy.com/JudgeOnline/problem.php?id=4820