题意:给出有M道题,T个队伍,和一个值N。给出每个队答对每一题的概率,现在要求满足下面两个条件的概率:
①每个队至少做出一道题
②做出最多题的队伍做题数不能小于N
思路:可以转化成所有队伍至少做出一道题的概率-所有队伍做题数都大于等于1并且小于N的概率。这个可以用dp求出,dp[i][j]表示前i题做出j道的概率。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
double P[maxn][55],dp[55][55];
int M,T,N;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d%d",&M,&T,&N))
{
if(M==0&&T==0&&N==0) break;
double tmp,ans=1,ans2=1;
for(int i=1;i<=T;++i)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int j=1;j<=M;++j)
{
scanf("%lf",&P[i][j]);
tmp*=(1.0-P[i][j]);
}
for(int j=1;j<=M;++j)
for(int k=0;k<=j;++k)
{
if(k!=0) dp[j][k]=dp[j-1][k]*(1.0-P[i][j])+dp[j-1][k-1]*P[i][j];
else dp[j][k]=dp[j-1][k]*(1.0-P[i][j]);
}
tmp=0;
for(int j=1;j<N;++j)
tmp+=dp[M][j];
ans2*=tmp;
ans*=(1-dp[M][0]);
}
ans=ans-ans2;
printf("%.3lf\n",ans);
}
return 0;
}