POJ 2151 Check the difficulty of problems

题意:一场ACM比赛有T支队伍参加,一共有m道题,给出每个队伍解出每一道题的可能性。求每只队伍至少解决一道题,且至少有一支队伍解决的问题数大于等于n的概率。(0 < M <= 30,1 < T <= 1000,0 < N <= M)

解法:概率DP。设d[i][j][k]表示第i支队伍,前j道题,解出k道的概率。则d[i][j][k] = d[i][j-1][k-1] * p[i][j] + d[i][j-1][k] * p[i][j]。

   然后ans1 = ∏(1 - d[i][m][0])(0 <= i <= T),ans2 = ∏(d[i][m][1] + d[i][m][2] + ... + d[i][m][n-1])(0 <= i <= T),所求为ans1 - ans2。

tag:概率DP

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-11-14 23:07
 4  * File Name: DP-POJ-2151.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 
10 using namespace std;
11 
12 #define CLR(x) memset(x, 0, sizeof(x))
13 
14 double p[1005][100], d[1005][40][40];
15 
16 int main()
17 {
18     int m, t, n;
19     while (scanf ("%d%d%d", &m, &t, &n) != EOF && m){
20         for (int i = 0; i < t; ++ i)
21             for (int j = 1; j <= m; ++ j)
22                 scanf ("%lf", &p[i][j]);
23 
24         CLR (d);
25         for (int i = 0; i < t; ++ i){
26             d[i][0][0] = 1;
27             for (int j = 1; j <= m; ++ j)
28                 for (int k = 0; k <= m; ++ k){
29                     d[i][j][k] = d[i][j-1][k] * (1 - p[i][j]);
30                     if (!k) continue;
31                     d[i][j][k] += d[i][j-1][k-1] * p[i][j];
32                 }
33         }
34 
35         double ans = 1.0;
36         for (int i = 0; i < t; ++ i)
37             ans *= (1 - d[i][m][0]);
38         double tmp = 1.0;
39         for (int i = 0; i < t; ++ i){
40             double sum = 0.0;
41             for (int j = 1; j < n; ++ j)
42                 sum += d[i][m][j];
43             tmp *= sum;
44         }
45         ans -= tmp;
46         printf ("%.3f
", ans);
47     }
48     return 0;
49 }
View Code
------------------------------------------------------------------
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。
原文地址:https://www.cnblogs.com/plumrain/p/POJ_2151.html