概率期望问题总结
Posted 桂月二四
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了概率期望问题总结相关的知识,希望对你有一定的参考价值。
1.转化为dp问题。
哈利波特要去抢银行,第i个银行有mi个金币,有pi的风险率被抓。问总风险率不超过P的情况下最多能抢多少金币。
想要计算风险是比较复杂的,因此我们考虑反面,计算安全率(安全率就是所抢银行的安全率之积,一个银行的安全率=1-pi)。
这就是一个背包问题。计f[i] 为抢到金币i所需的最大安全率
#include <bits/stdc++.h>
#include<ext/rope>
#define pb push_back
#define debug(x) cerr<<#x<<'='<<x<<'\\n'
#define debugg(x,y) cerr<<#x<<'='<<x<<','<<#y<<'='<<y<<'\\n'
#define FOR(a,b,c) for(int a=(b),a##_end=(c);a<=a##_end;++a)
#define ROF(a,b,c) for(int a=(b),a##_end=(c);a>=a##_end;--a)
#define FASTIO() cin.sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 200010 ,M = 1000010,mod = 998244353;const double eps = 1e-9;
ll qmi(ll,ll);
template<typename T>inline bool chkmin(T &x,const T &y){return y<x?x=y,1:0;}
template<typename T>inline bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int n,m,d;
int a[N];double p[N];
double P;
double f[N];
signed main()
{
int cas;read(cas);
int cnt = 0;
while(cas--)
{
printf("Case %d: ",++cnt);
cin>>P;read(n); P = 1-P;
memset(f,0,sizeof f);
for(int i=1;i<=n;i++)
{
scanf("%d%lf",&a[i],&p[i]);
p[i] = 1-p[i];
}
f[0] = 1;
for(int i=1;i<=n;i++)
{
for(int j=10000;j>=a[i];j--)
f[j] = max(f[j],f[j-a[i]]*p[i]);
}
for(int i=10000;i>=0;i--)
if(f[i]>=P)
{
cout<<i<<'\\n';
break;
}
}
return 0;
}
ll qmi(ll a,ll b) {ll res=1;a%=mod; for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
2.运用公式计算期望
计E(x) 为从x走到终点所需代价/时间/…/ 的期望,假设x的下一步能够到达的点为x1,x2,…,xk ,所需代价/时间/…/ 为w1,w2,…wk,其概率分别为p1,p2…,pk,那么E(x) = p1*(w1+E(x1))+p2*(w2+E(x2))+…+pk*(wk+E(xk)) ,一般可以采用记忆化搜索来完成。
注意:在有些题目中,p1=p2=…=pk=1/k 公式化简为E(x) = 1/k(w1+E(x1)+w2+E(x2)+…+wk+E(wk))
例1:绿豆蛙的归宿
这里E(x) 代表从点x走到终点路径的期望,E(1)即为答案
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010,M = 200010;
int ne[M],h[N],e[M],w[M],idx;
int k[N];
double f[N];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int main()
{
memset(h, -1, sizeof h);
int n,m;cin>>n>>m;
int a,b,c;
while(m--)
{
cin>>a>>b>>c;
add(b,a,c);
k[a]++;
}
for(int i=n;i>=1;i--)
{
for(int j = h[i];~j;j = ne[j])
{
int s = e[j];
f[s]+=1.0/k[s]*(w[j]+f[i]);
}
}
printf("%.2lf",f[1]);
return 0;
}
例2:Race to 1 Again
题意:每个数字有相等的概率除以自己的某个约数,求这个数变为1的步数期望。
这里的E(x)为数字x变为1步长的期望。
x可以变为x1,x2…,xk (这些数是他的约数,包括1(x1)和本身(xk))
于是E(x) = 1/k *(1+E(x1)+1+E(x2)+…+1+E(xk))
将等式左右乘以k 得 kE(x) = k+E(x1)+E(x2)+…+E(xk)
由于xk就是x ,所以
(k-1) E(x) = k+E(x1)+E(x2)+…+E(xk-1)
于是可以算出E(x)
注意:由于此时x是可以走到本身的,如果不对等式加以处理就会陷入死循环。
#include <bits/stdc++.h>
#include<ext/rope>
#define pb push_back
#define debug(x) cerr<<#x<<'='<<x<<'\\n'
#define debugg(x,y) cerr<<#x<<'='<<x<<','<<#y<<'='<<y<<'\\n'
#define FOR(a,b,c) for(int a=(b),a##_end=(c);a<=a##_end;++a)
#define ROF(a,b,c) for(int a=(b),a##_end=(c);a>=a##_end;--a)
#define FASTIO() cin.sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
using namespace __gnu_cxx;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 200010 ,M = 1000010,mod = 998244353;
const double eps = 1e-9;
ll qmi(ll,ll);
template<typename T>inline bool chkmin(T &x,const T &y){return y<x?x=y,1:0;}
template<typename T>inline bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int n,m,d;
int a[N];
double ans;
double mp[N];
double dfs(int n)
{
// debug(n);
// system("pause");
if(n==1) return 0;
if(fabs(mp[n])>eps) return mp[n];
vector<int> yue;
for(int i=1;i<=n/i;i++)
{
if(n%i==0)
{
yue.pb(i);
if(i!=n/i) yue.pb(n/i);
}
}
int d = yue.size();
sort(yue.begin(),yue.end());
double zi = 1;
for(int i=1;i<d;i++)
{
zi+=1+dfs(n/yue[i]);
}
return mp[n] = 1.0*zi/(d-1);
}
signed main()
{
int cas;read(cas);
int cnt = 0;
while(cas--)
{
read(n);
printf("Case %d: ",++cnt);
printf("%.10lf\\n",dfs(n));
}
return 0;
}
ll qmi(ll a,ll b) {ll res=1;a%=mod; for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
3.纯数学题(高中数学)
给定一年的年数,求最少的人,是的这些人中有两个人生日相同的概率>=0.5
比较简单,可以参考别人的题解
持续更新中…
以上是关于概率期望问题总结的主要内容,如果未能解决你的问题,请参考以下文章