ZOJ3640-Help Me Escape 概率dp
题意:
在一个迷宫中有n条路经,你会被随机传送到一条路径,每条路径有一个挑战难度ci,你最初有一个战斗力f,如果你的战斗力大于ci,那么呆在那里ti天就可以成功逃出迷宫。如果你的战斗力小于等于ci,那么你的战斗力会加上ci,并且消耗一天时间。问你逃出迷宫的天数的期望
题解:
因为访问路径不同的顺序会影响最后的结果 例如,如果有多个c[i]大于f,且你第一个就遇见那个最大c[i],那么呆上ti天就可以出来了 这样子的天数肯定少 而且一条路径可能会遇见多次,所以dfs来遍历就行
如果dfs过程中遇见f大于ci,那么加上ti天就可以return了
否则,那就使f加上ci,然后加上1天,接着去dfs下一层
代码:
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<iostream> using namespace std; #define mem(a) memset(a,0,sizeof(a)) typedef long long ll; const int maxn=105; const int N=10005; const int INF=1e9; const double blo=(1.0+sqrt(5.0))/2.0; double dp[50000]; int v[maxn],n; double dfs(int x) { if(dp[x]>0) return dp[x]; for(int i=1;i<=n;++i) { if(x>v[i]) { dp[x]+=floor(blo*1.0*v[i]*v[i])/n; } else { dp[x]+=(dfs(x+v[i])+1)/n; } } return dp[x]; } int main() { int f; while(~scanf("%d%d",&n,&f)) { mem(dp); for(int i=1;i<=n;++i) { scanf("%d",&v[i]); } /* 因为访问路径不同的顺序会影响最后的结果 例如,如果有多个v[i]大于f,且你第一个就遇见那个最大v[i],那么之后都是加上ti就行 这样子的天数肯定少 而且一条路径可能会遇见多次,所以dfs来遍历就行 */ printf("%.3lf\n",dfs(f)); } return 0; }