概率DP

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 }

 

 

 

你可能感兴趣的:(dp)