水水的~
题意给出t道题目,m个队伍,冠军至少要做出n题,给出每个队伍做出每一题的概率,要求冠军至少做出n题并且所有队伍做出至少1题的概率。
要求的可以转化为p(左右队伍做出>=1题)-p(所有队伍做出>=1题并且<n题)。
用DP[i][j][k]表示第i队做完第j题后做出k题的概率,就很容易了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
double dp[1111][33][33], p[1111][33];
int m, t, n;
int main () {
while (cin >> m >> t >> n && n+m+t) {
for (int i = 1; i <= t; i++) {
for (int j = 1; j <= m; j++)
cin >> p[i][j];
}
memset (dp, 0, sizeof dp);
for (int i = 1; i <= t; i++) {
dp[i][0][0] = 1.0;
for (int j = 1; j <= m; j++) {
for (int k = 0; k <= j; k++) {
if (!k)
dp[i][j][k] = dp[i][j-1][k]*(1-p[i][j]);
else
dp[i][j][k] = dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j]);
}
}
}
double ans = 1.0;
for (int i = 1; i <= t; i++) { //所有人做出至少一道
double cur = 0.0;
for (int j = 1; j <= m; j++) {
cur += dp[i][m][j];
}
ans *= cur;
}
double ans2 = 1.0;
for (int i = 1; i <= t; i++) {
double cur = 0.0;
for (int j = 1; j < n; j++) {
cur += dp[i][m][j];
}
ans2 *= cur;
}
printf ("%.3f\n", ans-ans2);
}
return 0;
}