Check the difficulty of problems
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 2674 Accepted: 1163
Description
Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually expect 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 expect 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 should not be processed.
Output
For each test case, please output the answer in a separate line. The result should be rounded to three digits after the decimal point.
Sample Input
2 2 2
0.9 0.9
1 0.9
0 0 0
Sample Output
0.972
Source
POJ Monthly,鲁小石
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int M, T, N;
double pro[1010][35];
double f[35][35];
void calcf(int num){
int i, j;
for (i = 1; i <= M; i++) f[0][i] = 0;
f[0][0] = 1;
for (i = 1; i <= M; i++){
f[i][0] = f[i - 1][0] * (1 - pro[num][i]);
for (j = 1; j <= i; j++){
f[i][j] = f[i - 1][j] * (1 - pro[num][i]) + f[i - 1][j - 1] * pro[num][i];
// printf("f[%d][%d] = %f\n", i, j, f[i][j]);
}
}
}
int main(){
int i, j, k;
double p, q, ans;
while(scanf("%d%d%d", &M, &T, &N), M && N && T){
for (i = 1; i <= T; i++){
for (j = 1; j <= M; j++){
scanf("%lf", &pro[i][j]);
}
}
ans = 1;
p = 1;
for (i = 1; i <= T; i++){
q = 1;
for (j = 1; j <= M; j++){
q *= (1 - pro[i][j]);
}
p *= (1 - q);
}
ans -= 1 - p;
// printf("pa = %f\n", 1 - p);
p = 1;
for (i = 1; i <= T; i++){
q = 0;
calcf(i);
for (j = 1; j < N; j++){
q += f[M][j];
}
p *= q;
}
// printf("pb = %f\n", p);
ans -= p;
printf("%0.3f\n", ans);
}
return 0;
}
/*
看了遍概率的课件...来推推:
A:至少1队0题
B:每队1..N-1题
A和B是互不相容的, P(AB) = 0
求P(~A~B)
P(~A|~B) = P(~A) + P(~B) - P(~A~B)
P(~A|~B) = 1 - P(AB)
综上P(~A~B) = P(~A) + P(~B) - 1 = 1 - P(A) - P(B)
P(B)DP的去求,f[i][j]为前i道题做出j道的概率
*/