POJ 2151 Check the difficulty of problems(概率DP)
不会做,概率论学的不好啊。看的这个题解,这里面好像有点错误,sum[i][j]数组,表示第i个队伍解出0,1,2...j的题目概率的和。这个问题主要是转化,和怎么计算,状态转移很常见,如果想不出怎么计算,肯定挂。初始化问题,让我错了几次,这是多久没写题了啊。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <map> 5 #include <cstring> 6 #include <cmath> 7 using namespace std; 8 #define eps 1e-7 9 double dp[1001][31][31]; 10 double p[1001][31]; 11 double sum[1001][31]; 12 int main() 13 { 14 int n,m,t,i,j,k; 15 double ans,temp; 16 while(scanf("%d%d%d",&m,&t,&n)!=EOF) 17 { 18 if(!m&&!t&&!n) break; 19 ans = 1; 20 temp = 1; 21 memset(dp,0,sizeof(dp)); 22 memset(sum,0,sizeof(sum)); 23 memset(p,0,sizeof(p)); 24 for(i = 1; i <= t; i ++) 25 { 26 for(j = 1; j <= m; j ++) 27 { 28 scanf("%lf",&p[i][j]); 29 } 30 } 31 for(i = 1; i <= t; i ++) 32 { 33 dp[i][1][1] = p[i][1]; 34 dp[i][1][0] = 1 - p[i][1]; 35 for(j = 2; j <= m; j ++) 36 { 37 dp[i][j][0] = dp[i][j-1][0]*(1 - p[i][j]); 38 for(k = 1; k <= j; k ++) 39 { 40 dp[i][j][k] = (1 - p[i][j])*dp[i][j-1][k] + p[i][j]*dp[i][j-1][k-1]; 41 } 42 } 43 } 44 for(i = 1; i <= t; i ++) 45 { 46 sum[i][0] = dp[i][m][0]; 47 for(j = 1; j <= m; j ++) 48 { 49 sum[i][j] = dp[i][m][j] + sum[i][j-1]; 50 } 51 } 52 for(i = 1; i <= t; i ++) 53 { 54 ans = ans*(sum[i][m] - sum[i][0]); 55 } 56 for(i = 1; i <= t; i ++) 57 { 58 temp = temp*(sum[i][n-1] - sum[i][0]); 59 } 60 printf("%.3lf\n",ans-temp+eps); 61 } 62 return 0; 63 }