poj 2151 Check the difficulty of problems 概率DP

解题链接:

http://www.cnblogs.com/183zyz/archive/2012/09/13/2683524.html

这题算是概率DP里的简单题,由于各种独立,所有设dp[i][j][k]为第i个队在做到第j个题时解了k个题的概率,针对第j个题,有解出和未解出两种可能。所以

就会有dp[i][j][k] += dp[i][j-1][k-1]*p[i][j]; //解出

dp[i][j][k] += dp[i][j-1][k]*(1-p[i][j]);//未解出

然后题目要求算每个队至少解出一个且存在一个解出的题目数>=n 的概率

设p1为每个队至少解出一个题的概率,p2为每个队解出的题目数>=1 && <n的概率,p3为要求得概率。

有p1 = p2+p3,p3 = p1-p2.初始化时令所有的概率都为0,除了dp[][0][0] = 1//只有没有做题,解题个数为0时是一个必然事件。

贴代码:

 1 #include <cstdio>
 2 #include<cstring>
 3 double p[1005][33];
 4 double dp[1005][33][33];
 5 int main()
 6 {
 7 //    freopen("in.c","r",stdin);
 8     int m,t,n;
 9     while(scanf("%d%d%d",&m,&t,&n))
10     {
11         if(m==0&&t==0&&n==0) break;
12         for(int i=0; i<t; ++i)
13             for(int j=1; j<=m; ++j)
14                 scanf("%lf",&p[i][j]);
15         memset(dp,0,sizeof(dp));
16         for(int i=0; i<t; ++i)
17             dp[i][0][0]=1;
18         for(int i=0; i<t; ++i)
19         {
20             for(int j=1; j<=m; ++j)
21             {
22                 dp[i][j][0] += dp[i][j-1][0]*(1-p[i][j]);
23                 for(int k=1; k <= m; ++k)
24                 {
25                     dp[i][j][k] += dp[i][j-1][k-1]*p[i][j];
26                     dp[i][j][k] += dp[i][j-1][k]*(1-p[i][j]);
27                 }
28             }
29         }
30         double f1=1;
31         for(int i=0; i<t; ++i)
32             f1 *= (1 - dp[i][m][0]);
33         double f2=1;
34         for(int i=0; i<t; ++i)
35         {
36             double f3 =0;
37             for(int k=1; k<n; ++k)
38                 f3 +=dp[i][m][k];
39             f2 *= f3;
40         }
41         printf("%.3f
",f1-f2);
42     }
43     return 0;
44 }
View Code
原文地址:https://www.cnblogs.com/allh123/p/3264423.html