概率与期望dp

定义:

概率:事件A发生的可能性,计作P(A)

期望:事件A结果的平均大小,记住E(x)

​ E(x)=每种结果的大小与其概率的乘积的和

注意计算概率时需要考虑是否要用容斥原理

期望dp时注意有时要用倒序枚举

其实本质和其他的dp没什么区别

例题

概率充电器

题面

题意:n个充电元件由n-1条导线连通,每个充电原件自身是否直接充电以及每条导线是否导电都由概率决定,求进入充电状态的元件个数的期望

1<=n<=500000

树形换根概率dp,注意使用容斥原理

第一遍dfs:计算出f[i]表示由子树i通电的概率

第二遍dfs:计算出从父亲节点来电的概率,再用容斥原理加在一起

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define maxn 500100
int n;
int fir[maxn],nxt[maxn*2],vv[maxn*2];
double edge[maxn*2],q[maxn];
int tot=0;
double ans=0;
void add(int u,int v,double w)
{
nxt[++tot]=fir[u];
fir[u]=tot;
vv[tot]=v;
edge[tot]=w;
}
double h[maxn];
void dfs1(int u,int fa)
{
h[u]=q[u];
for(int i=fir[u];i;i=nxt[i])
{
int v=vv[i];
if(v==fa)continue;
dfs1(v,u);
h[u]=h[u]+h[v]*edge[i]-h[u]*h[v]*edge[i];
}
}
void dfs2(int u,int fa)
{
for(int i=fir[u];i;i=nxt[i])
{
int v=vv[i];
if(v==fa)continue;
if(fabs(1-h[v]*edge[i])>(1e-7))
{
double t=(h[u]-h[v]*edge[i])/(1-h[v]*edge[i]);
h[v]=h[v]+t*edge[i]-h[v]*t*edge[i];
ans+=h[v];
}else ans+=1;
dfs2(v,u);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int a,b;double p;scanf("%d%d%lf",&a,&b,&p);
add(a,b,p/100);add(b,a,p/100);
}
for(int i=1;i<=n;i++)scanf("%lf",&q[i]),q[i]/=100;
dfs1(1,0);
ans=h[1];
dfs2(1,0);
printf("%0.6lf",ans);
return 0;
}

换教室

题目

题意:小A的学校可以视为一个v个点的无向图,他有n门课程要按顺序上课,其中第i门课程要在节点ai进行,但还有一个备选地点bi。现在小A有m个申请机会,若申请第i门课,那么将有ki的概率使课程搬到bi进行。每门课最多申请一次,m次机会不必全部用完。他如何申请才能最小化在上课地点间移动的距离的期望值。求该期望值。

v<=300,n,m<=200

先用floyd求出任意两点的距离

再令f[i][j][0/1]表示前i节课申请m次且第i节课申请/不申请的最小期望值

注意double类型需要手动赋初值

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,v,e;
double f[2010][2010],dp[2010][2010][2],k[2010];
int c[2010],d[2010];
double mymin(double x,double y)
{
return x<y?x:y;
}
int main()
{
scanf("%d%d%d%d",&n,&m,&v,&e);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n;i++)scanf("%d",&d[i]);
for(int i=1;i<=n;i++)scanf("%lf",&k[i]);
for(int i=1;i<=v;i++)for(int j=1;j<=v;j++)f[i][j]=1e9;
for(int i=1;i<=v;i++)f[i][i]=0;
for(int i=1;i<=e;i++)
{
int a,b;double w;scanf("%d%d%lf",&a,&b,&w);
f[a][b]=f[b][a]=min(f[a][b],w);
}
for(int kk=1;kk<=v;kk++)
{
for(int i=1;i<=v;i++)
{
for(int j=1;j<=v;j++)
{
f[i][j]=f[j][i]=min(f[i][j],f[i][kk]+f[kk][j]);
}
}
}
for(int i=1;i<=n;i++)for(int j=0;j<=m;j++)
{
dp[i][j][0]=1e9;dp[i][j][1]=1e9;
}
dp[1][0][0]=dp[1][1][1]=0;
for(int i=2;i<=n;i++)
{
for(int j=0;j<=min(m,i);j++)
{
dp[i][j][0]=mymin(dp[i-1][j][0]+f[c[i]][c[i-1]],dp[i-1][j][1]+k[i-1]*f[c[i]][d[i-1]]+(1-k[i-1])*f[c[i]][c[i-1]]);
if(j!=0)
dp[i][j][1]=mymin(dp[i-1][j-1][0]+f[c[i-1]][c[i]]*(1-k[i])+f[c[i-1]][d[i]]*k[i],dp[i-1][j-1][1]+f[c[i-1]][c[i]]*(1-k[i])*(1-k[i-1])+f[c[i-1]][d[i]]*(1-k[i-1])*k[i]+f[d[i-1]][c[i]]*k[i-1]*(1-k[i])+f[d[i-1]][d[i]]*k[i-1]*k[i]);
}
}
double ans=1e9;
for(int i=0;i<=m;i++)
{
ans=mymin(ans,dp[n][i][0]);ans=mymin(ans,dp[n][i][1]);
}
printf("%0.2lf",ans);
return 0;
}

奖励关

[题目]

题意:有n轮游戏和m种宝物,每种宝物有分数Pi(可以为负),每轮游戏会等概率抛出一种宝物,你可以选择吃或不吃。第i种宝物还有一个限制集合Si,表示只有在Si中的宝物都吃过后,才能吃第i种宝物。

1<=n<=100 1<=m<=15

期望状压dp

f[i][S]表示在第1轮到第i−1轮内宝物是否取过的状态为S,第i轮到第n轮的最大期望得分,进行逆推。

采用逆推的原因如下:

如果要从当前状态S0转移到目标状态S1,那么直接f[i+1][s1]+=f[i][s0]/n的转移方法是错误的,因为f[i+1][n]不一定有n种被转移到的方式,有可能因为限制集合的原因,有些状态不能转移到f[i+1][s],但如果采用逆推,那么我们是从一个合法的状态转移到当前状态,就不存在这样的问题,大多数期望dp都可以采用逆推的方法。

那么逆推如何转移呢:

枚举第k种宝物,可以取或不取,

如果能取,f[i][s]+=max(f[i+1][s],f[i+1][s|(1<<(k-1))]+p[k])

如果不能取,f[i][s]+=f[i+1][s]

然后f[i][s]/=n

答案为f[1][0]

#include <iostream>
#include <cstdio>
using namespace std;
int n,k;
double f[110][1<<18],value[110];
int sta[110];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
scanf("%lf",&value[i]);
int x;scanf("%d",&x);
while(x!=0)
{
sta[i]=sta[i]|(1<<(x-1));
scanf("%d",&x);
}
}
for(int i=n;i>=1;i--)
{
for(int j=0;j<=(1<<k)-1;j++)
{
for(int kk=1;kk<=k;kk++)
{
if((j|sta[kk])==j)
{
f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(kk-1))]+value[kk]);
}
else f[i][j]+=f[i+1][j];
}
f[i][j]=(double)f[i][j]*1.0/k;
}
}
printf("%.6lf",f[1][0]);
return 0;
}

期望与概率dp的更多相关文章

  1. 【整理】简单的数学期望和概率DP

    数学期望 P=Σ每一种状态*对应的概率. 因为不可能枚举完所有的状态,有时也不可能枚举完,比如抛硬币,有可能一直是正面,etc.在没有接触数学期望时看到数学期望的题可能会觉得很阔怕(因为我高中就是这么 ...

  2. POJ2096Collecting Bugs(数学期望,概率DP)

    问题: Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material ...

  3. 动态规划之经典数学期望和概率DP

    起因:在一场训练赛上.有这么一题没做出来. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829 题目大意:有三个人,他们分别有\(X,Y,Z\)块钱 ...

  4. 数学期望和概率DP题目泛做(为了对应AD的课件)

    题1: Uva 1636 Headshot 题目大意: 给出一个000111序列,注意实际上是环状的.问是0出现的概率大,还是当前是0,下一个还是0的概率大. 问题比较简单,注意比较大小: A/C & ...

  5. [转]概率DP总结 by kuangbin

    概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...

  6. LOOPS 概率dp

    题意:迷宫是一个R*C的布局,每个格子中给出停留在原地,往右走一个,往下走一格的概率,起点在(1,1),终点在(R,C),每走一格消耗两点能量,求出最后所需要的能量期望 简单概率dp 注意   原地不 ...

  7. BZOJ 1415 [NOI2005]聪聪与可可 (概率DP+dfs)

    题目大意:给你一个无向联通图,节点数n<=1000.聪聪有一个机器人从C点出发向在M点的可可移动,去追赶并吃掉可可,在单位时间内,机器人会先朝离可可最近的节点移动1步,如果移动一步机器人并不能吃 ...

  8. poj 2096 Collecting Bugs (概率dp 天数期望)

    题目链接 题意: 一个人受雇于某公司要找出某个软件的bugs和subcomponents,这个软件一共有n个bugs和s个subcomponents,每次他都能同时随机发现1个bug和1个subcom ...

  9. zoj 3822 Domination (概率dp 天数期望)

    题目链接 参考博客:http://blog.csdn.net/napoleon_acm/article/details/40020297 题意:给定n*m的空棋盘 每一次在上面选择一个空的位置放置一枚 ...

随机推荐

  1. 关于Linux fontconfig 字体库的坑

    01.安装字体软件 yum -y install fontconfig 然后把字体拷过去就行了 cd /usr/share/fonts fc-list 这是查看 02.拷贝字体到指定目录 cp sim ...

  2. python — 函数基础知识(二)

    目录 1 返回值 2 作用域 3 函数小高级 4 函数中高级 1 返回值 def func(arg): # .... return 9 # 返回值为9 默认:return None val = fun ...

  3. Devexpress WinForm TreeList的三种数据绑定方式(DataSource绑定、AppendNode添加节点、VirtualTreeGetChildNodes(虚拟树加载模式))

    第一种:DataSource绑定,这种绑定方式需要设置TreeList的ParentFieldName和KeyFieldName两个属性,这里需要注意的是KeyFieldName的值必须是唯一的. 代 ...

  4. 【KMP】Censoring

    [KMP]Censoring 题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his ...

  5. 教你如何进行移动端APP测试

    1.安全测试(权限) 1)软件权限:其中包括发送信息,拨打电话,链接网络,访问手机信息,联系人信息等等 2)数据在本地的存储.传输等 3)执行某些操作时导致的输入有效性验证.授权.数据加密等方面 4) ...

  6. China Union Pay helper

    static string proxyIpAddress = AppConfig.GetProxyIpAddress; static string proxyUserName = AppConfig. ...

  7. ES5中一些重要的拓展

    1.对象的拓展 ①Object.create(obj, {age:{value:18, writable:true, configurable:true, enumerable:true}); 以指定 ...

  8. 抽奖JQ

    <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8 ...

  9. 如何提高后台服务应用问题的排查效率?日志 VS 远程调试

    转眼间,距离Jerry最近一篇文章推送已经过去了一个多月的时间了. 公众号更新的频率降低,不是因为Jerry偷懒,而是由于从春节过后,我所在的SAP成都研究院数字创新空间整个团队,一直在忙一个5月份需 ...

  10. PHPExcel的简单使用

    一.在做PHP开发时,我们会遇到把数据导出变为execl表格的形式,使用PHPExcel就可以,下载地址:https://github.com/PHPOffice/PHPExcel,下载后会显示这么多 ...