poj 2151 Check the difficulty of problems(概率dp)

poj double 就得交c++,我交G++错了一次

题目:http://poj.org/problem?id=2151

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

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

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

设dp[i][j][k]表示第i个队在前j道题中解出k道的概率

则:

dp[i][j][k]=dp[i][j-1][k-1]*p[j][k]+dp[i][j-1][k]*(1-p[j][k]);

先初始化算出dp[i][0][0]和dp[i][j][0];

设s[i][k]表示第i队做出的题小于等于k的概率

则s[i][k]=dp[i][M][0]+dp[i][M][1]+``````+dp[i][M][k];

 

则每个队至少做出一道题概率为P1=(1-s[1][0])*(1-s[2][0])*```(1-s[T][0]);

每个队做出的题数都在1~N-1的概率为P2=(s[1][N-1]-s[1][0])*(s[2][N-1]-s[2][0])*```(s[T][N-1]-s[T][0]);

 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<stack>
 6 #include<queue>
 7 #include<iomanip>
 8 #include<cmath>
 9 #include<map>
10 #include<vector>
11 #include<algorithm>
12 using namespace std;
13 
14 double dp[2010][100][100],s[2010][100],p[2010][100];
15 int main()
16 {
17     int m,n,t,i,j,k;
18     double p1,p2;
19     while(cin>>m>>t>>n)
20     {
21         if(m==0&&n==0&&t==0)
22         break;
23         for(i=1; i<=t; i++)
24         for(j=1; j<=m; j++)
25         cin>>p[i][j];
26         for(i=1; i<=t; i++)
27         {
28             dp[i][0][0]=1;
29             for(j=1; j<=m; j++)
30             dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j]);
31             for(j=1; j<=m; j++)
32             for(k=1; k<=j; k++)
33             dp[i][j][k]=dp[i][j-1][k-1]*p[i][j]+dp[i][j-1][k]*(1-p[i][j]);
34             s[i][0]=dp[i][m][0];
35             for(k=1; k<=m; k++)
36             s[i][k]=s[i][k-1]+dp[i][m][k];
37         }
38         p1=1; p2=1;
39         for(i=1; i<=t; i++)
40         {
41             p1*=(1-s[i][0]);
42             p2*=(s[i][n-1]-s[i][0]);
43         }
44         printf("%.3lf\n",p1-p2);
45     }
46     return 0;
47 }

 

posted @ 2013-08-21 16:44  水门  阅读(198)  评论(0编辑  收藏  举报