题意:比赛中有M道题,T个参赛队,pij表示第i队解出第j题的概率,
求每队至少解出一题,且冠军队至少解出N道题的概率
分析:要求每队至少解出一题,且冠军队至少解出N道题的概率
则原来的所求的概率可以转化为:
每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2
设dp[i][j][k]表示第i队在前j道题解出k道题的概率
则dp[i][j][k]=dp[i][j-1][k-1]*pij+dp[i][j-1][k]*(1-pij)
设sum[i][j]为第i队至多解出j道题的概率
则 sum[i][j]=dp[i][M][0]+dp[i][M][1]+...+dp[i][M][j]
sum[i][M]-sum[i][0]为第i队至少解出1道题的概率
sum[i][N-1]-sum[i][0]为第i队解出 [1,N-1]道题的概率
#include<stdio.h> #include<string.h> double p[1005][32],dp[32][32],sum[32],p1,p2; int main() { int t,m,n,i,j,k; while(scanf("%d%d%d",&m,&t,&n)!=EOF){ if(t==0&&m==0&&n==0) break; for(i=1;i<=t;i++) for(j=1;j<=m;j++) scanf("%lf",&p[i][j]); memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); p1=p2=1.0; for(i=1;i<=t;i++){ dp[0][0]=1.0; for(j=1;j<=m;j++){ dp[j][0]=dp[j-1][0]*(1-p[i][j]); for(k=1;k<=j;k++) dp[j][k]=dp[j-1][k]*(1-p[i][j])+dp[j-1][k-1]*p[i][j]; } sum[0]=dp[m][0]; for(j=1;j<=m;j++) sum[j]=sum[j-1]+dp[m][j]; p1*=(sum[m]-sum[0]); p2*=(sum[n-1]-sum[0]); } printf("%.3lf\n",p1-p2); } return 0; }
poj 2151 Check the difficulty of problems (dp,概率)
原文地址:http://blog.csdn.net/acm_code/article/details/40680515