天天看点

poj 2151 Check the difficulty of problems (概率与期望DP)

Check the difficulty of problems
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 7334 Accepted: 3166

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,鲁小石

[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);
	}
}