码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ2151】Check the difficulty of problems

时间:2018-05-27 20:54:16      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:问题   span   include   names   怎么   using   可以转化   技术   size   

题意

   某场比赛有M道问题,T支队伍,和数字N给出每支队伍解决每道问题的概率。 问这场比赛满足下面两个条件的概率

   1.每支队伍至少做出一道题

   2.冠军队至少做出N道题。

分析

 条件2是不是可以转化为 至少有一支队做出N道及以上道题。

 这个题主要是概率,其次才是dp,而且好像不算概率DP。

 我们来倒推一下。

 设p2为每支队伍做出来的题数都在(1-N-1)的概率。p1为每只队伍至少做出来一道题的概率。那么答案就是p1-p2。

 然后我们再来想怎么求p1和p2。设s[i][j]为第i支队伍做出来题数小于等于j的概率。那么

 p1=(1-s[1][0])*(1-s[2][0])*...*(1-s[T][0]).

 p2=(s[1][N-1]-s[1][0])*(s[2][N-1]-s[2][0])*...*(s[T][N-1]-s[T][0])。

 然后再往前推。s[i][j]该怎么求?

 我们发现队伍与队伍之间没有关系,于是我们可以每支队伍都通过dp求解。对于每支队伍k

  我们令f[i][j]为前i个问题中做出来j个题的概率 f[i][j]=f[i-1][j]*(1-P[k][j])+f[i-1][j-1]*P[k][j];

  然后 s[k][j]=sum(f[M][l])(0<=l<=j)

  就是这个样子。

  这个题的DP是最基础的,但是概率那里我觉得不是特别好想。。(可能因为我菜吧···)

  

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 const int maxn=1000+100;
 8 const int maxm=50;
 9 int M,T,N;
10 double P[maxn][maxm];
11 double f[maxm][maxm],s[maxn][maxm];
12 int main(){
13     while(scanf("%d%d%d",&M,&T,&N)!=EOF&&(M||T||N)){
14         memset(P,0,sizeof(P));
15         for(int i=1;i<=T;i++){
16             for(int j=1;j<=M;j++){
17                 scanf("%lf",&P[i][j]);
18             }
19             memset(f,0,sizeof(f));
20             f[0][0]=1.0;
21             for(int j=1;j<=M;j++){
22                 for(int k=0;k<=j;k++){
23                     if(k==0)
24                       f[j][k]=f[j-1][k]*(1-P[i][j]);
25                     else
26                      f[j][k]=f[j-1][k-1]*P[i][j]+f[j-1][k]*(1-P[i][j]);
27                 }
28             }
29             double sum=0;
30             for(int j=0;j<=M;j++){
31                 sum+=f[M][j];
32                 s[i][j]=sum;
33             }
34         }
35         double p1,p2;
36         p1=p2=1.0;
37         for(int i=1;i<=T;i++){
38             p1*=(1-s[i][0]);
39         }
40         for(int i=1;i<=T;i++){
41             p2*=(s[i][N-1]-s[i][0]);
42         }
43         double ans=p1-p2;
44         printf("%.3f\n",ans);
45     }
46 return 0;
47 }
View Code

 

【POJ2151】Check the difficulty of problems

标签:问题   span   include   names   怎么   using   可以转化   技术   size   

原文地址:https://www.cnblogs.com/LQLlulu/p/9097252.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!