题意:
给出M个题目由N个队来做时每个队作对每道题的概率问满足下列条件的概率为
1:每个队最少完成一道题目
2:最少有一个队完成的题目为T
分析:
这是一个概率问题
记A:每个队最少完成一道题目 B:最少有一个队完成的题目为T p【i】【j】为第i队作对第j题的概率
那么ans=f(A)-f(A*~B)
我们可以用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】
dp的初始化:显然dp【i】【0】【0】=1;
dp【i】【j】【0】=∏(1-p【i】【k】)1<=k<=m
记dpp【i】【j】表示第i个队最少做j题的概率
那么dpp【i】【j】=∑dp【i】【m】【k】0<=k<=m
A:∏dpp【i】【0】
B:∏(dpp【i】【T-1】-dpp【i】【0】)
ACcode:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
#define maxn 1005
#define inf 0x3f3f3f3f3f
double p[1005][35];
double dp[1005][35][35];
double dpp[1005][35];
int main(){
int m,n,t;
while(scanf("%d%d%d",&m,&n,&t)&&(m+n+t)){
memset(dp,0,sizeof(dp));
memset(dpp,0,sizeof(dpp));
double a=1,b=1;
for(int i=1;i<=n;++i){
double tmp=1;
for(int j=1;j<=m;++j){
scanf("%lf",&p[i][j]);
tmp*=(1-p[i][j]);
dp[i][j][0]=tmp;
}
a=a*(1-tmp);
}
// cout<<a<<'\12';
for(int i=1;i<=n;++i)dp[i][0][0]=1;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)
for(int k=1;k<=t&&k<=j;++k)
dp[i][j][k]=dp[i][j-1][k-1]*p[i][j]+(1-p[i][j])*dp[i][j-1][k];
dpp[i][0]=dp[i][m][0];
for(int k=1;k<=m;k++)dpp[i][k]=dpp[i][k-1]+dp[i][m][k];
}
for(int i=1;i<=n;++i)b*=(dpp[i][t-1]-dpp[i][0]);
printf("%.3f\n",a-b);
/* for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
for(int k=1;k<=t&&k<=j;++k)
printf("dp[%d][%d][%d]=%lf ",i,j,k,dp[i][j][k]);
putchar('\12');.
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)
printf("dpp[%d][%d]=%lf ",i,j,dpp[i][j]);
putchar('\12');
}
*/
}
return 0;
}