Check the difficulty of problems
Time limit:2000 ms |
|
Memory limit:65536 K |
Total submissions:8903 |
|
Accepted:3772 |
Description
Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually failed CT the contest result satisfy the following two terms:
1. All of the teams solve at least one problem.
2. The Champion (one of those teams that solve the most problems) solves at least a certain number of problems.
Now the organizer has studied out the contest problems, and through the result of preliminary contest, the organizer can estimate the probability that a certain team can successfully solve a certain problem.
Given the number of contest problems m, the number of teams t, and the number of problems n that the organizer has CT the champion solve at least. we also assume that team I solves problem J with the probability Pij (1 <= I <= T, 1 <= j <= m ). well, can you calculate the probability that all of the teams solve at least one problem, and at the same time the champion team solves at least N problems?
Input
The input consists of several test cases. the first line of each test case contains three integers m (0 <m <= 30), t (1 <t <= 1000) and N (0 <n <= m ). each of the following T lines contains M floating-point numbers in the range of [0, 1]. in these t lines, the J-th number in the I-th line is just PIJ. A test case of M = t = n = 0 indicates the end of input, and shoshould not be processed.
Output
For each test case, please output the answer in a separate line. The result shocould be rounded to three digits after the decimal point.
Sample Input
2 2 20.9 0.91 0.90 0 0
Sample output
0.972
Source
Poj monthly, Lu Xiaoshi
Solution
Probability DP
Define $ DP [I] [J] [k] $ to indicate the probability that the $ I $ team has done the $ J $ question to the $ K $ question. The transfer equation is clear.
Then, define $ s [I] [J] $ to indicate that the probability of matching the $ I $ team does not exceed $ J $, $ s [I] [J] = \ sum {DP [I] [T] [k]}, 0 <= k <= J $
Then the probability that all teams are correct for at least one question is $ p1 = \ prod {(1-s [I] [0])} $
Because the champion army is at least $ N $, the final probability is $ P1 $ minus the probability that each team does not reach $ N $: $ \ prod {s [I] [n-1]} $. Note that each team has at least one correct question, because it is a Recursive Transfer to get $ S $, the contribution of $0 $ cannot be included, so $ S $ is recursive from 2.
Code
#include<iostream>#include<cstdio>using namespace std;double dp[1005][35][35], s[1005][35], p[1005][35];int m, t, n;int main() { while(scanf("%d%d%d", &m, &t, &n) != EOF) { if(m == 0 && t == 0 && n == 0) break; for(int i = 1; i <= t; i ++) for(int j = 1; j <= m; j ++) scanf("%lf", &p[i][j]); for(int i = 1; i <= t; i ++) { dp[i][0][0] = 1; for(int j = 1; j <= m; j ++) { dp[i][j][0] = dp[i][j - 1][0] * (1 - p[i][j]); for(int k = 1; k <= j; k ++) dp[i][j][k] = dp[i][j - 1][k - 1] * p[i][j] + dp[i][j - 1][k] * (1 - p[i][j]); } for(int j = 0; j <= m; j ++) s[i][j] = dp[i][m][j]; } for(int i = 1; i <= t; i ++) for(int j = 2; j <= m; j ++) s[i][j] = s[i][j] + s[i][j - 1]; double p1 = 1; for(int i = 1; i <= t; i ++) p1 *= (1 - s[i][0]); double p2 = 1; for(int i = 1; i <= t; i ++) p2 *= s[i][n - 1]; if(n == 1) p2 = 0; printf("%0.3lf\n", p1 - p2); } return 0;}
[Poj] 2151: Check the difficulty of problems [probability DP]