题目:题目链接
题目的意思很简单,就是说给你M道题,N支队伍,以及希望冠军解出的题目数m,保证每支队伍至少解出一题,分别给出
每支队伍解出每道题目的概率,求这样的概率是多少?
分析:dp,f[i][j]表示第i个队伍做对第j题的概率。g[i][j][k]表示第i个队伍对于前j题而言做对k道的概率。g[i]
[j][k] = g[i][j - 1][k - 1] * (f[i][j]) + g[i][j - 1][k] * (1 - f[i][j]);
有了所有的g,我们就可以求出每个队至少做对1题的概率:ans *= 1 - g[i][n][0];
再减去每个队都只做对1到m-1题的概率(把每个队做对1~m-1题的概率加和,并把各队结果相乘)
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <stack>
using namespace std;
#define maxn 35
#define maxt 1005
int n, t, m;
double f[maxt][maxn];
double g[maxt][maxn][maxn];
int main()
{
while (scanf("%d%d%d", &n, &t, &m))
{
if(n==0 && t == 0 && m==0)
break;
double ans =1;
for (int i =0; i < t; i++)
for (int j =1; j <= n; j++)
scanf("%lf", &f[i][j]);
memset(g, 0, sizeof(g));
for (int i =0; i < t; i++)
{
g[i][0][0] =1;
for (int j =1; j <= n; j++)
{
g[i][j][0] = g[i][j -1][0] * (1- f[i][j]);
for (int k =1; k <= j; k++)
g[i][j][k] = g[i][j -1][k -1] * (f[i][j]) + g[i][j -1][k] * (1- f[i][j]);
}
}
for (int i =0; i < t; i++)
ans *=1- g[i][n][0];
double temp =1;
for (int i =0; i < t; i++)
{
double sum =0;
for (int j =1; j < m; j++)
sum += g[i][n][j];
temp *= sum;
}
ans -= temp;
printf("%.3f\n", ans);
}
return 0;
}