http://poj.org/problem?id=2151
题意 :t个队伍m道题,i队写对j题的概率为pij。冠军是解题数超过n的解题数最多的队伍之一,求满足有冠军且其他队伍解题数都大于等于1的概率。
f[i][j][w]表示i队到第j题总共解出w道题的概率.
为了避免重复计数;
pa=所有队伍到最后一道题时的解题数都大于1的概率;
pb=所有队伍到最后一道题时解题数都小于n的概率;
答案为pa-pb.
代码如下
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=1010; 9 const double eps=1e-8; 10 const int modn=998244353; 11 int m,n,t; 12 double f[maxn][35][35]={}; 13 double f1[maxn][35]={}; 14 double a[maxn][35]; 15 int main(){ 16 while(~scanf("%d%d%d",&m,&t,&n)){ 17 memset(f,0,sizeof(f)); 18 if(m==0&&n==0&&t==0)break; 19 for(int i=1;i<=t;i++){ 20 for(int j=1;j<=m;j++){ 21 scanf("%lf",&a[i][j]); 22 } 23 } 24 double t1=1,t2=1,t3,t4; 25 for(int i=1;i<=t;i++){ 26 f[i][0][0]=1; 27 for(int j=1;j<=m;j++){ 28 for(int w=0;w<=j;w++){ 29 if(j-1>=w)f[i][j][w]+=f[i][j-1][w]*(1.0-a[i][j]); 30 f[i][j][w]+=f[i][j-1][w-1]*a[i][j]; 31 } 32 } 33 t3=0,t4=0; 34 for(int j=1;j<=m;j++){ 35 t3+=f[i][m][j]; 36 if(j<n){ 37 t4+=f[i][m][j]; 38 } 39 } 40 t1*=t3;t2*=t4; 41 } 42 printf("%.3f ",t1-t2); 43 } 44 return 0; 45 }