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 }

 

你可能感兴趣的:(check)