POJ-2151 Check the difficulty of problems---概率DP好题

题目链接:

https://vjudge.net/problem/POJ-2151

题目大意:

ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率

问 每队至少解出一题且冠军队至少解出N道题的概率。

解题思路:

看了题解才恍然大悟,还是做题少没思路。

 

要求:每队至少解出一题 且 冠军队至少解出N道题的概率

由于冠军队可以不止一队,即允许存在并列冠军

则原来的所求的概率可以转化为:

每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2

 

注意初始条件,其他递推即可

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 const int maxn = 1005;
 6 double p[maxn][35];//p[i][j]表示第i个队做出第j题的概率
 7 double dp[maxn][35][35];//dp[i][j][k]表示第i个队前j道题做出k题的概率
 8 double sum[maxn][35];//sum[i][j]表示第i个队伍做出至多k题的概率(前缀和)
 9 int main()
10 {
11     int n, m, t;
12     while(cin >> m >> t >> n && m)
13     {
14         for(int i = 1; i <= t; i++)
15         {
16             for(int j = 1; j <= m; j++)
17                 cin >> p[i][j];
18         }
19         memset(dp, 0, sizeof(dp));
20         memset(sum, 0, sizeof(sum));
21         for(int i = 1; i <= t; i++)
22         {
23             dp[i][1][1] = p[i][1];
24             dp[i][1][0] = 1.0 - p[i][1];
25             for(int j = 2; j <= m; j++)
26             {
27                 for(int k = 0; k <= j; k++)
28                 {
29                     dp[i][j][k] = dp[i][j - 1][k] * (1 - p[i][j]) + dp[i][j - 1][k - 1] * p[i][j];
30                 }
31             }
32         }
33         for(int i = 1; i <= t; i++)
34         {
35             sum[i][0] = dp[i][m][0];
36             for(int j = 1; j <= m; j++)
37                 sum[i][j] = sum[i][j - 1] + dp[i][m][j];
38         }
39         double p1 = 1, p2 = 1;
40         //p1表示所有队伍至少做出1题的概率
41         //p2表示所有队伍做题数目在1-n-1之间
42         for(int i = 1; i <= t; i++)
43             p1 *= (sum[i][m] - sum[i][0]),
44             p2 *= (sum[i][n - 1] - sum[i][0]);
45         printf("%.3f
", p1 - p2);
46     }
47 }
原文地址:https://www.cnblogs.com/fzl194/p/8971182.html