题目链接:
https://vjudge.net/problem/POJ-2151
题目大意:
ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率
问 每队至少解出一题且冠军队至少解出N道题的概率。
解题思路:
看了题解才恍然大悟,还是做题少没思路。
要求:每队至少解出一题 且 冠军队至少解出N道题的概率
由于冠军队可以不止一队,即允许存在并列冠军
则原来的所求的概率可以转化为:
每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2
注意初始条件,其他递推即可
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 const int maxn = 1005; 6 double p[maxn][35];//p[i][j]表示第i个队做出第j题的概率 7 double dp[maxn][35][35];//dp[i][j][k]表示第i个队前j道题做出k题的概率 8 double sum[maxn][35];//sum[i][j]表示第i个队伍做出至多k题的概率(前缀和) 9 int main() 10 { 11 int n, m, t; 12 while(cin >> m >> t >> n && m) 13 { 14 for(int i = 1; i <= t; i++) 15 { 16 for(int j = 1; j <= m; j++) 17 cin >> p[i][j]; 18 } 19 memset(dp, 0, sizeof(dp)); 20 memset(sum, 0, sizeof(sum)); 21 for(int i = 1; i <= t; i++) 22 { 23 dp[i][1][1] = p[i][1]; 24 dp[i][1][0] = 1.0 - p[i][1]; 25 for(int j = 2; j <= m; j++) 26 { 27 for(int k = 0; k <= j; k++) 28 { 29 dp[i][j][k] = dp[i][j - 1][k] * (1 - p[i][j]) + dp[i][j - 1][k - 1] * p[i][j]; 30 } 31 } 32 } 33 for(int i = 1; i <= t; i++) 34 { 35 sum[i][0] = dp[i][m][0]; 36 for(int j = 1; j <= m; j++) 37 sum[i][j] = sum[i][j - 1] + dp[i][m][j]; 38 } 39 double p1 = 1, p2 = 1; 40 //p1表示所有队伍至少做出1题的概率 41 //p2表示所有队伍做题数目在1-n-1之间 42 for(int i = 1; i <= t; i++) 43 p1 *= (sum[i][m] - sum[i][0]), 44 p2 *= (sum[i][n - 1] - sum[i][0]); 45 printf("%.3f ", p1 - p2); 46 } 47 }