hdu 4336 http://acm.hdu.edu.cn/showproblem.php?pid=4336
比较简单的一道概率DP。
一般概率DP都是从后向前推,对于这道题目,因为n不是很大, 所以可以用二进制,用一个数表示一种状态。
1表示该卡片已经被搜集过,0表示还没有
所以dp[2^n-1]的期望值为0
dp[i]=dp[i]*sum + pi*dp[i+2^i] +1 ;
sum表示这次bags里面没有卡片或者是已经搜集过的卡片的概率
最后求出dp[0]即可。
bupt 200 http://acm.bupt.edu.cn/onlinejudge/newoj/showProblem/show_problem.php?problem_id=200
这道题目也是从后往前面推导,每一个点可以走向它的右方或者下方,或者还是他自身。
不过有一点需要注意当一个点的3个概率值分别为1.0, 0.0 , 0.0时,该点的期望值应为无限大。
对于期望值无限大的就不用再加入计算了。
View Code
1 # include<stdio.h> 2 # include<string.h> 3 # include<stdlib.h> 4 # define N 1005 5 # define INF 10000000 6 struct node{ 7 double s,l,d; 8 }P[N][N]; 9 double dp[N][N]; 10 int main() 11 { 12 int i,j,R,C; 13 double sum; 14 while(scanf("%d%d",&R,&C)!=EOF) 15 { 16 for(i=1;i<=R;i++) 17 for(j=1;j<=C;j++) 18 { 19 scanf("%lf%lf%lf",&P[i][j].s,&P[i][j].l,&P[i][j].d); 20 } 21 dp[R][C]=0; 22 for(i=R;i>=1;i--) 23 { 24 for(j=C;j>=1;j--) 25 { 26 if(i==R && j==C) continue; 27 //dp[i][j]=dp[i][j]*P[i][j].s+dp[i][j+1]*P[i][j].l+dp[i+1][j]*P[i][j].d+1; 28 if(P[i][j].s==1) {dp[i][j]=INF;} 29 else 30 { 31 sum=0; 32 if(dp[i][j+1]==INF && dp[i+1][j]==INF) {dp[i][j]=INF;continue;} 33 if(dp[i][j+1]!=INF) sum+=dp[i][j+1]*P[i][j].l; 34 if(dp[i+1][j]!=INF) sum+=dp[i+1][j]*P[i][j].d; 35 dp[i][j]=(sum+2)/(1-P[i][j].s); 36 } 37 } 38 } 39 printf("%.3lf\n",dp[1][1]); 40 } 41 return 0; 42 }