思路 :dp[i] [j] [k] 为做了第i队,做了j到题,对了k道题的概率
那么dp[i] [j] [k] = dp[i] [j-1] [k] * (1-p[i] [j] ) + dp[i] [j-1] [k-1]*(p[i] [j])
那么题目所求的可以转换成,每队至少写出一道题的概率,减去每队写出1—n-1道题的概率。由于是独立事件,所以要乘起来。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
using namespace std;
float f[1003][33];
float g[1003][33][33];
int main()
{
int tn,dn,n;
int i,j,k;
while(scanf("%d %d %d",&tn,&dn,&n)!=EOF)
{
if(tn==0&&dn==0&&n==0)
break;
memset(g,0,sizeof(g));
memset(f,0,sizeof(f));
for(i=1; i<=dn; i++)
for(j=1; j<=tn; j++)
scanf("%f",&f[i][j]);
for(i=1; i<=dn; i++)
{
g[i][1][0]=1-f[i][1];
g[i][1][1]=f[i][1];
}
for(i=1; i<=dn; i++)
for(j=2; j<=tn; j++)
for(k=0; k<=j; k++)
{
if(k==j)
g[i][j][k] = g[i][j-1][k-1]*f[i][j];
else if(k==0)
g[i][j][k] = g[i][j-1][k]*(1-f[i][j]);
else
g[i][j][k] = g[i][j-1][k-1]*f[i][j] + g[i][j-1][k]*(1-f[i][j]);
}
double all=1;
for(i=1; i<=dn; i++)
all*=(1-g[i][tn][0]);
double midall=1;
for(i=1; i<=dn; i++)
{
double everyd=0;
for(j=1; j<n; j++)
{
everyd+=g[i][tn][j];
}
midall*=everyd;
}
all-=midall;
printf("%.3f\n",all);
}
return 0;
}