poj 2151Check the difficulty of problems<概率DP>

链接:http://poj.org/problem?id=2151

题意:一场比赛有 T 支队伍,共 M 道题, 给出每支队伍能解出各题的概率~

    求 :冠军至少做出 N 题且每队至少做出一题的概率~

思路:设dp[i][j][k] 为 第 i 队 在前 j 题共解出 k 题的概率~

   那么 dp[i][j][k]=dp[i][j-1][k-1]*p[i][j-1] + dp[i][j-1][k]*(1-p[i][j-1]) ~

     s[i][0] 为 第 i 队至多解出N-1题的概率,s[i][1] 为第 i 队至少解出一题的概率~

   那么就可以解出来了~

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 using namespace std;

 5 int M, T, N;

 6 double dp[1005][35][35], s[1005][2], p[1005][35];

 7 int main( )

 8 {

 9     while(scanf("%d%d%d", &M, &T, &N)!= EOF, M+N+T){

10         for( int i=0; i<T; ++ i ){

11             for( int j=0; j<M; ++ j ){

12                 scanf("%lf", &p[i][j]);

13             }

14         }

15         memset(dp, 0, sizeof dp);

16         memset(s, 0, sizeof s);

17         double p1=1,p2=1;

18         for( int i=0; i<T; ++ i ){

19             dp[i][0][0]=1;

20             for( int j=1; j<=M; ++ j ){

21                 for( int k=0; k<=j; ++ k ){

22                     dp[i][j][k]=dp[i][j-1][k-1]*p[i][j-1]+dp[i][j-1][k]*(1-p[i][j-1]);

23                     if(j==M && k>0){

24                         s[i][1]+=dp[i][j][k];

25 

26                         if(k<N){

27                             s[i][0]+=dp[i][j][k];

28                         }

29                     }

30                 }

31             }

32 

33             p1*=s[i][1];

34             p2*=s[i][0];

35         }

36         printf("%.3f\n", p1-p2);

37     }

38     return 0;

39 }
View Code

 

 

你可能感兴趣的:(check)