poj2151

题意:在acm比赛中,n题,t队。给出每个队做对每题的概率,问每队至少对一题,至少有一队做对至少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题的概率加和,并把各队结果相乘)

View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
usingnamespace std;

#define maxn 35
#define maxt 1005

int n, t, m;
double f[maxt][maxn];
double g[maxt][maxn][maxn];

int main()
{
//freopen("t.txt", "r", stdin);
while (scanf("%d%d%d", &n, &t, &m), n | t | m)
{
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);
}
return0;
}
posted @ 2011-07-01 20:18  金海峰  阅读(1319)  评论(3编辑  收藏  举报