zoj-3604 Help Me Escape[概率dp]

来源:互联网 发布:个人淘宝客网站备案 编辑:程序博客网 时间:2024/05/18 01:42
题目意思: 一个吸血鬼,每天有n条路走,
每次随机选一条路走,每条路有限制,
如果当这个吸血鬼的能力大于某个值c[i],
那么只需要花费ti(ti = (1.0 + sqrt(5.0))/2 * c[i] * c[i])
天的时间就可以逃出去,否则,花费1天的时间,
吸血鬼的能力增加c[i],花费1天的时间,然后继续下一天的尝试。

求逃出去的期望。

被这道题的四舍五入坑惨了。

令E(f)表示吸血鬼在战斗力为f的时候逃出去的期望。

对于走每条路 i,概率为1/n有两种考虑

(1)f>c[i],此时吸血鬼可以从这条路逃走 E(f)+=t[i]*(1/n);

(2)f<=c[i],此时吸血鬼得继续下一天的尝试,E(f+c[i])+=(E(f)+1)*(1/n);这里得将公式逆推刚好也是E(f)+=(1+E(f+c[i]))*(1/n);

所以E(f)=∑{t[i]*(1/n)}+∑{(E(j+c[j])+1)*(1/n)}            i表示f>c[i]的路,j表示f<=c[i]的路

#include <stdio.h>#include <string.h>#include <algorithm>#include <math.h>using namespace std;const int maxn=10008;const double eps=1E-8;const double ft=(1.0 + sqrt(5.0))/2.0;int n;int c[maxn];double t[maxn],E[maxn*4];double DP(int f){ double &res=E[f];if(res>eps) return res;for(int i=1;i<=n;++i){if(f>c[i])res+=int(t[i])*1.0/n;else res+=(1+DP(f+c[i]))*1.0/n;}return res;}void init(){memset(E,0,sizeof(E)); t[0]=0;for(int i=1;i<=n;++i){t[i]=ft* c[i] * c[i];}}int main(){int f;while(~scanf("%d%d",&n,&f)){for(int i=1;i<=n;++i)scanf("%d",c+i);init();printf("%.3lf\n",DP(f));}return 0;}


0 0
原创粉丝点击