题目链接:http://poj.org/problem?id=2151
题目大意:有M个题目,T支队伍,第i个队伍做出第j个题目的概率为Pij,问每个队伍都至少做出1个题并且至少有一个队伍做出N题的概率。
先定义状态dp[i][j][k],代表第i支队伍从前j个题目里正好做出k题的概率。
有:dp[i][j][k] = dp[i][j-1][k]*(1-p[i][j]) + dp[i][j-1][k-1]*p[i][j];
然后设f[i]为前i支队伍里,每队至少做出一个题并且至少有一个队伍做出N题的概率。
那么f[i] = f[i-1]*(第i支队伍做出不少于1题的概率) + (1-f[i-1]-存在队伍没做出题的概率)*(第i支队伍做了不少于N题的概率)
上面这个是个全概率公式
于是乎:
1 ///#pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <cmath> 10 #include <numeric> 11 #include <iterator> 12 #include <iostream> 13 #include <cstdlib> 14 #include <functional> 15 #include <queue> 16 #include <stack> 17 #include <string> 18 #include <cctype> 19 using namespace std; 20 #define PB push_back 21 #define MP make_pair 22 #define SZ size() 23 #define ST begin() 24 #define ED end() 25 #define CLR clear() 26 #define ZERO(x) memset((x),0,sizeof(x)) 27 typedef long long LL; 28 typedef unsigned long long ULL; 29 typedef pair<int,int> PII; 30 const double EPS = 1e-8; 31 32 const int MAX_T = 1111; 33 const int MAX_M = 33; 34 35 int M,T,N; 36 double p[MAX_T][MAX_M],f[MAX_T],any[MAX_T],dp[MAX_T][MAX_M][MAX_M]; 37 38 int main(){ 39 while( ~scanf("%d%d%d",&M,&T,&N), M!=0&&T!=0&&N!=0 ) { 40 ZERO(dp); 41 ZERO(f); 42 ZERO(any); 43 for(int i=1;i<=T;i++) { 44 for(int j=1;j<=M;j++) { 45 scanf("%lf",&p[i][j]); 46 } 47 } 48 for(int i=1;i<=T;i++){ 49 dp[i][0][0] = 1.0; 50 for(int j=1;j<=M;j++) { 51 dp[i][j][0] = dp[i][j-1][0]*(1-p[i][j]); 52 } 53 for(int j=1;j<=M;j++){ 54 for(int k=1;k<=j;k++){ 55 dp[i][j][k] = dp[i][j-1][k]*(1-p[i][j]) + dp[i][j-1][k-1]*p[i][j]; 56 } 57 } 58 for(int j=1;j<=M;j++){ 59 for(int k=1;k<=M;k++){ 60 dp[i][j][k] += dp[i][j][k-1]; 61 } 62 } 63 } 64 65 f[0] = 0.0; 66 any[0] = 1.0; 67 for(int i=1;i<=T;i++){ 68 any[i] = any[i-1]*(1.0-dp[i][M][0]); 69 } 70 for(int i=1;i<=T;i++){ 71 any[i] = 1.0 - any[i]; 72 } 73 any[0] = 0.0; 74 75 for(int i=1;i<=T;i++){ 76 f[i] = f[i-1]*(dp[i][M][M]-dp[i][M][0]) + (1.0-f[i-1]-any[i-1])*(dp[i][M][M]-dp[i][M][N-1]); 77 } 78 79 printf("%.3f\n",f[T]); 80 } 81 return 0; 82 }
时间: 2024-09-27 04:39:12