概率期望问题总结
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:Dice (III)
题意,给定一个n面的骰子,不停投掷,求所有面都出现时投掷次数的期望。
假定f[i]代表出现i个面的期望。
如图,当出现i-1个面时,下一次操作有(i-1)/n的概率不会出现新的面,有(n-i+1)/n的概率会出现新面,因此出现新面的期望是概率的倒数,即为n/(n-i+1)
所以f[i] = f[i-1]+n/(n-i+1)
#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 dp[N];
signed main()
int cas;read(cas);
int cnt = 0;
while(cas--)
dp[1] = 1;
read(n);
for(int i=2;i<=n;i++)
dp[i] = dp[i-1]+1.0*n/(n-i+1);
printf("Case %d: %.10lf\\n",++cnt,dp[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:Where to Run
题意:
给你n(n<15)个点,m条无向边及其权值,你是一个刚偷完东西的小偷,身后有警察追你,因此你需要从1号点开始进行逃亡,在每个点你都有≥1个选择:
1、停留在原地5分钟
2、假设你在u号点,与u节点直接相连的点有v1,v2,…,vx号点,如果其中的某些节点到达它后可以通过这个节点遍历所有的点,那么你就可以选择这个点。选择每个合法点的概率是相等的,求你无路可走的时间期望
思路:
1、对于每个点u(编号0~n-1), 先找出所有可选择的点,假设有k个可选点
2、dp[zt][u]表示经过的点的状态为zt,目前在u点时走完所有点的时间期望(v为u的可选点)
则
化简可得
3、至于能否走完所有的点,做一下记忆化搜索就可以了
#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 = 20 ,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][N];
double f[1<<N][N];
bool ok[1<<N][N];
bool vis[1<<N][N];
int mm;
bool dfs(int st,int k)
if(st==mm)
f[st][k] = 0;
return true;
if(vis[st][k]) return ok[st][k];
vis[st][k] = true;
f[st][k] = 0;
int cnt = 0;
for(int i=0;i<n;i++)
if(a[i][k]&&!(st>>i&1))
if(dfs(st|(1<<i),i))
++cnt;
f[st][k]+=f[st|(1<<i)][i]+a[i][k];
ok[st][k] = 1;
if(!ok[st][k]) return false;
f[st][k] = (f[st][k]+5.0)/cnt;
return true;
signed main()
int cas;read(cas);
int T = 0;
while(cas--)
read(n),read(m);
memset(a,0,sizeof a);
memset(ok,0,sizeof ok);
memset(vis,0,sizeof vis);
mm = (1<<n)以上是关于概率期望问题总结的主要内容,如果未能解决你的问题,请参考以下文章