题意 : 举办一次比赛不容易,为了不让题目太难,举办方往往希望能够讲出的题目满足两点,1是所有的队伍都至少能够解出一个题目,2是冠军队至少能解出确定数量的题目,最后让你求的是每个队伍至少解出一道题并且冠军队伍解出N道题的概率.
思路 : 我觉得吧,搞ACM不容易,唉,概率这玩意儿,一不小心漏掉一个就完啦。。。。首先呢,概率得好好求,其次呢DP得会一些。。。。
这个题的思路我觉得小优姐的CSDN已经说得很详细了http://blog.csdn.net/lyy289065406/article/details/6648579
样例解释 : 2 2 2
0.9 0.9
1 0.9
第一行M,T,N代表着M道题,T个队伍,希望冠军队做出N道题。接下来是T行M列,表示(i,j)点表示队伍 i 做对 j题的概率是多少。
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> using namespace std ; const int maxn = 35 ; const int maxm = 1010 ; double f[maxm][maxn]; double dp[maxm][maxn][maxn]; int main() { int M,T,N ;//题目数,队伍数,冠军队做出题目数 while(~scanf("%d %d %d",&M,&T,&N)) { if(M == 0&&N == 0&& T == 0) break ; memset(dp,0,sizeof(dp)); for(int i = 1 ; i <= T ; i++) { for(int j = 1 ; j <= M ; j++) scanf("%lf",&f[i][j]); } for(int i = 1 ; i <= T ; i++) { dp[i][0][0] = 1.0 ; for(int j = 1 ; j <= M ; j++) { dp[i][j][0] = dp[i][j-1][0]*(1-f[i][j]); for(int k = 1 ; k <= j ; k++) { dp[i][j][k] = dp[i][j-1][k-1]*f[i][j]+dp[i][j-1][k]*(1-f[i][j]); } } } double p1 = 1.0 ; for(int i = 1 ; i <= T ; i++) p1 *= (1 - dp[i][M][0]) ; double p2 = 1.0 ; for(int i = 1 ; i <= T ; i++) { double sum = 0 ; for(int j = 1 ; j < N ; j++) sum += dp[i][M][j]; p2 *= sum ; } printf("%.3f ",p1-p2); } return 0; }