Check the difficulty of problems
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 Sample Output Source POJ Monthly,鲁小石 |
[Submit] [Go Back] [Status] [Discuss]
题目大意:t支队伍,m个问题,要求每个队伍至少回答对1个问题,至少有一支队伍回答出n个或以上个问题。求事件发生的概率。
题解:概率与期望DP
对于每只队伍分别进行DP
f[i][j]表示到第i到题目回答对j道题目的概率。
f[i][j]=f[i-1][j]*(1-p[j])+f[i-1][j-1]*p[j] 其中p[j]表示这支队伍回答对第j个题的概率。
那么我们再计算的时候可以先计算总答案再减去不合法的方案。
这里总方案指所有对于回答对任意题(非0)的概率-所有队伍回答的题数都在[1..n-1]之间的概率。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100
using namespace std;
int n,m,t;
double f[N][N];
int main()
{
freopen("a.in","r",stdin);
while (true) {
scanf("%d%d%d",&m,&t,&n);
if (m==0&&t==0&&n==0) break;
double ans=1; double ans1=1;
for (int i=1;i<=t;i++) {
f[0][0]=1;
for (int j=1;j<=m;j++) {
double x; scanf("%lf",&x);
for (int k=j;k>=0;k--) {
f[j][k]=f[j-1][k]*(1.0-x);
if (k) f[j][k]+=f[j-1][k-1]*x;
}
}
//for (int j=0;j<=m;j++) printf("%.3lf ",f[m][j]);
//printf("\n");
double sum=0;
for (int j=1;j<n;j++) sum+=f[m][j];
ans*=(1.0-f[m][0]);
ans1*=sum;
}
printf("%.3lf\n",ans-ans1);
}
}