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
", p1-p2);
37     }
38     return 0;
39 }
View Code
原文地址:https://www.cnblogs.com/jian1573/p/3248936.html