1. All of the teams solve at least one problem.
2. The champion (One of those teams that solve the most problems) solves at least a certain number of problems.
Now the organizer has studied out the contest problems, and through the result of preliminary contest, the organizer can estimate the probability that a certain team can successfully solve a certain problem.
Given the number of contest problems M, the number of teams T, and the number of problems N that the organizer expect the champion solve at least. We also assume that team i solves problem j with the probability Pij (1 <= i <= T, 1<= j <= M). Well, can you calculate the probability that all of the teams solve at least one problem, and at the same time the champion team solves at least N problems?
Input
Output
Sample Input
2 2 2 0.9 0.9 1 0.9 0 0 0
Sample Output
0.972
题意+题解
ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率
问 每队至少解出一题且冠军队至少解出N道题的概率。
解析:DP
设dp[i][j][k]表示第i个队在前j道题中解出k道的概率
则:
dp[i][j][k]=dp[i][j-1][k-1]*p[j][k]+dp[i][j-1][k]*(1-p[j][k]);
先初始化算出dp[i][0][0]和dp[i][j][0];
设s[i][k]表示第i队做出的题小于等于k的概率
则s[i][k]=dp[i][M][0]+dp[i][M][1]+``````+dp[i][M][k];
则每个队至少做出一道题概率为P1=(1-s[1][0])*(1-s[2][0])*```(1-s[T][0]);
每个队做出的题数都在1~N-1的概率为P2=(s[1][N-1]-s[1][0])*(s[2][N-1]-s[2][0])*```(s[T][N-1]-s[T][0]);
最后的答案就是P1-P2
每个队至少做出一道题的概率-p2,就是减法原理,意思就是去除了全是1-(n-1)的情况,然后就是
赢的队至少解出了n道题。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 #define N 1007 7 #define M 57 8 using namespace std; 9 10 int m,n,t; 11 double f[N][M][M],z[N][M],gx[N][M]; 12 13 14 int main() 15 { 16 while(~scanf("%d%d%d",&m,&t,&n)&&(n+m+t)) 17 { 18 for (int i=1;i<=t;i++) 19 for (int j=1;j<=m;j++) 20 scanf("%lf",&z[i][j]); 21 memset(f,0,sizeof(f)),memset(gx,0,sizeof(gx)); 22 for (int i=1;i<=t;i++) 23 { 24 f[i][0][0]=1; 25 for (int j=1;j<=m;j++) 26 f[i][j][0]=f[i][j-1][0]*(1-z[i][j]); 27 for (int j=1;j<=m;j++) 28 for (int k=1;k<=j;k++) 29 f[i][j][k]=f[i][j-1][k-1]*z[i][j]+f[i][j-1][k]*(1-z[i][j]); 30 gx[i][0]=f[i][m][0]; 31 for (int j=1;j<=m;j++) 32 gx[i][j]=gx[i][j-1]+f[i][m][j]; 33 } 34 double ans1,ans2; 35 ans1=ans2=1; 36 for (int i=1;i<=t;i++) 37 { 38 ans1=ans1*(1-gx[i][0]); 39 ans2=ans2*(gx[i][n-1]-gx[i][0]); 40 } 41 printf("%.3f\n",ans1-ans2); 42 } 43 }