题目大意
有t支队伍要比赛,做m道题,已知i队伍做j题做对的几率p[i][j],求所有队伍至少做一题并且冠军至少做n题的概率
题目分析
用f[i][j][k]表示第i支队伍做前j题做对k题的概率,那么
f[i][j][k]=f[i][j−1][k]∗(1−p[i][j])+f[i][j−1][k−1]∗p[i][j];
,边界:f[i][0][0]=1;这是显然的嘛。
那么每支队伍至少做一题的概率p1应该是(1-每支队伍一题都做不出的概率)的积嘛。
那么每支队伍都做出1到n-1题的概率是p2=
∑f[i][m][1...n−1]
,答案应该就是p1-p2
如果是G++最后输出要是”%.3f”
代码
#include<iostream>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
int m,t,n;
double p[1005][50],f[50][50];
int main()
{
int i,j,k,x,y;
while(1){
double p1=1.0,p2=1.0;
scanf("%d%d%d",&m,&t,&n);
if(!m&&!t&&!n)break;
for(i=1;i<=t;i++){
double tmp=1.0;
for(j=1;j<=m;j++){scanf("%lf",&p[i][j]);tmp*=(1.0-p[i][j]);}
p1=p1*(1.0-tmp);
}
for(i=1;i<=t;i++){
memset(f,0,sizeof(f));
f[0][0]=1.0;
for(j=1;j<=m;j++){
f[j][0]=f[j-1][0]*(1.0-p[i][j]);
for(k=1;k<=j;k++)
f[j][k]=f[j-1][k]*(1.0-p[i][j])+f[j-1][k-1]*p[i][j];
}
double tmp=0;
for(j=1;j<=n-1;j++)tmp+=f[m][j];
p2*=tmp;
}
printf("%.3f\n",p1-p2);
}
return 0;
}