博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU4405(期望DP)
阅读量:5092 次
发布时间:2019-06-13

本文共 1556 字,大约阅读时间需要 5 分钟。

又一道期望DP,其实这题与hdu4576那道概率DP很像(这道我也写了题解)。那么这两道一道求概率,一道求期望,又能放在一起对比一下了,期望和概率的求法的不同。

先总结一句话:一般求概率DP或者是递推的问题,都是正着推,从初始状态往结束状态(结束状态一般是此类题要求的状态)推,所以先得到(或者说先已知)的是靠近初始状态的状态,所以想要求的当前状态是由可转移到此状态的前N可能个状态推过来的;而一般求期望DP,都是逆着推,从结束状态往初始状态(初始状态往往是此类题要求的状态)推,所以先得到(或者说先已知)的是靠近结束状态的状态,所以想要求的当前状态是由此状态对应接下来的N可能个状态推过来的。

本题题意:数轴上有N+1个点(编号0~N),一个人玩游戏,从0出发,当到达N或大于N的点则游戏结束。每次行动掷骰子一次,骰子编号1-6,掷到多少就向前走几步,这个数轴上还有些特殊点,这些点类似飞行棋中的飞行点,只要到达这些点就可以直接飞到给定点。求总共投掷骰子次数的期望。

例如本题,倒着过来分析。用dp[i]表示在i位置时,距离游戏结束还要投掷次数的期望。显然dp[n]为0,需要求的是dp[0]。对于直接飞过去的点。例如用数组vis[]来表示,vis[a]=b,表示当到达a点时可以直接飞到b点,那么显然dp[vis[a]]=dp[a]。倒着推,dp[i](假设该点不属于可飞行的点)的下面一个状态有6种可能(即对应6种可能的骰子数),每种都是1/6的概率。所以for(int x=1;x<=6;x++)dp[i]+=dp[i+x]/6.0;dp[i]+=1;注意最后加玩每种可能性的期望后要+1,因为这6种可能性加起来只是下一个状态的期望,当前状态是他们的前一个状态,所以期望(直接理解为投掷骰子的次数)要+1。具体代码如下:

#include 
#include
#include
#include
#define ll long longdouble dp[100005];int vis[100005];int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ if((n+m)==0)break; memset(vis,-1,sizeof(vis)); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); vis[a]=b; } memset(dp,0,sizeof(dp)); for(int i=n-1;i>=0;i--){ if(vis[i]==-1){ for(int j=1;j<=6;j++){ dp[i]+=dp[i+j]/6.0; } dp[i]+=1; } else dp[i]=dp[vis[i]]; } printf("%.4lf\n",dp[0]); } return 0;}

 

 

转载于:https://www.cnblogs.com/kevinACMer/p/3724671.html

你可能感兴趣的文章
C#条件编译,发布多平台和多种选择性的项目
查看>>
python 笔记数据类型
查看>>
如何用php开启企业微信开发的回调模式
查看>>
UAC在注册表中的对应位置
查看>>
机器为什么可以学习(2)---一般化理论
查看>>
集合和Iterator迭代器
查看>>
IO—》File类
查看>>
Web前端学习笔记(三)——input标签的属性
查看>>
BZOJ.3262.陌上花开([模板]CDQ分治 三维偏序)
查看>>
BZOJ.1312.[Neerc2006]Hard Life(分数规划 最大权闭合子图)
查看>>
js的concat函数、join 、slice函数及二维数组的定义方式
查看>>
Vue的单页应用中如何引用单独的样式文件
查看>>
html5利用getObjectURL获取图片路径上传图片
查看>>
学习资料
查看>>
hread.interrupt()到底意味着什么
查看>>
寒假训练总结
查看>>
equals与==的区别
查看>>
spring 监听器
查看>>
[BZOJ 3709] Bohater
查看>>
Python 的字符编码
查看>>