标签:概率dp
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4808
被这道题坑惨了。
有一个吸血鬼被困了,有n条路可以逃出去,每条路有一个难度c[],他初始的战斗力是f,对于第i条路,若f > c[i]他花t[i]天就能出去,否则,他就停留一天,同时战斗力增加c[i]然后再选一条路走出去,他走每条路的概率是相同的。问他逃出去的天数的期望。
设dp[i]表示在战斗力为i时逃出去的期望值,那么可推出状态方程
dp[i] = 1/n * t[j](c[j] > i),dp[i] = 1/n * (1+dp[ i+c[j] ] )( c[j] <= i)。
需要注意的是终态的确定。当f > Max时,这时的期望值为总时间的平均值便是终态了,但是i + c[j]有可能大于Max+1,所以终态应该是Max*2。初始化时就忘乘2了。
还有就是t[i]是整数。
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> //#define LL __int64 #define LL long long #define eps 1e-8 #define PI acos(-1.0) using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 4010; double dp[10010]; int c[110]; double t[110]; int main() { int n,f; int Max; double sum_t,ave_t; while(~scanf("%d %d",&n,&f)) { Max = f; sum_t = 0; for(int i = 1; i <= n; i++) { scanf("%d",&c[i]); t[i] = (int) ( (1+sqrt(5))*0.5*c[i]*c[i] ); Max = max(Max,c[i]); sum_t += t[i]; } ave_t = sum_t/n; if(f > Max) { printf("%.3lf\n",ave_t); continue; } memset(dp,0,sizeof(dp)); for(int i = Max+1; i <= 20000; i++) dp[i] = ave_t; for(int i = Max; i >= f; i--) { for(int j = 1; j <= n; j++) { if(i > c[j]) { dp[i] += t[j]; } else { dp[i] += 1+dp[i+c[j]]; } } dp[i] /= n; } printf("%.3lf\n",dp[f]); } return 0; }
标签:概率dp
原文地址:http://blog.csdn.net/u013081425/article/details/39103415