POJ-2151 Check the difficulty of problems---probability DP problem

Topic link:

https://vjudge.net/problem/POJ-2151

Topic meaning:

In the ACM competition, there are M questions and T teams, and pij represents the probability that the i-th team solves the j-th question.

Ask the probability that each team solves at least one problem and the champion team solves at least N problems.

Problem solving ideas:

After reading the solution, I suddenly realized, but I still have no idea when I do the problem.

 

Requirement: Probability that each team solves at least one problem and the champion team solves at least N problems

Since the champion team can have more than one team, a tie for champions is allowed

Then the original probability can be transformed into:

The probability P1 that each team does at least one problem minus the probability P2 that each team does between 1 and N-1

 

 

Pay attention to the initial conditions, other recursion can be

1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4  using  namespace std;
 5  const  int maxn = 1005 ;
 6  double p[maxn][ 35 ]; // p[i][j] means The probability of the i-th team answering the jth question is 
7  double dp[maxn][ 35 ][ 35 ]; // dp[i][j][k] means that the first j question of the i-th team answers the k question Probability 
8  double sum[maxn][ 35 ]; // sum[i][j] represents the probability that the i-th team will do at most k questions (prefix sum) 
9  int main()
 10  {
11     int n, m, t;
12     while(cin >> m >> t >> n && m)
13     {
14         for(int i = 1; i <= t; i++)
15         {
16             for(int j = 1; j <= m; j++)
17                 cin >> p[i][j];
18         }
19         memset(dp, 0, sizeof(dp));
20         memset(sum, 0, sizeof(sum));
21         for(int i = 1; i <= t; i++)
22         {
23             dp[i][1][1] = p[i][1];
24             dp[i][1][0] = 1.0 - p[i][1];
25             for(int j = 2; j <= m; j++)
26             {
27                 for(int k = 0; k <= j; k++)
28                 {
29                     dp[i][j][k] = dp[i][j - 1][k] * (1 - p[i][j]) + dp[i][j - 1][k - 1] * p[i][j];
30                 }
31             }
32         }
33         for(int i = 1; i <= t; i++)
34         {
35             sum[i][0] = dp[i][m][0];
36             for(int j = 1; j <= m; j++)
37                 sum[i][j] = sum[i][j - 1 ] + dp[i][m][j];
 38          }
 39          double p1 = 1 , p2 = 1 ;
 40          // p1 represents the probability that all teams have at least 1 problem
 41          // p2 represents the number of problems that all teams have done Between 1-n-1 
42          for ( int i = 1 ; i <= t; i++ )
 43              p1 *= (sum[i][m] - sum[i][ 0 ]),
 44              p2 *= ( sum[i][n - 1 ] - sum[i][ 0 ]);
 45          printf( " %.3f\n " , p1 - p2);
 46      }
47 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325078584&siteId=291194637