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\n",f1-f2); 42 } 43 return 0; 44 }