您的位置:首页 > 其它

poj 2151 Check the difficulty of problems

2013-09-07 11:13 281 查看
   需要一定的概率基础,然后加上一定的dp基础就可以直接解决了,我概率也都忘得差不多了,竟然最后连pn是p1的子问题都分不清了,哎,糊涂啊。   i队做一题的概率非常好求(1减去一道题都没做出来的概率),然后所有队的概率相乘就是每队都至少做出一道题的概率,然后算出至少做出1道题,但不存在一个队做出的题数大于等于N的概率,然后2者相减(pn是p2的子问题),算pn的时候需要用到dp,主要的dp状态转移方程为:(dp[i][j]表示i道题做出j道的概率。)

for(int j=1;j<=M;++j)#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int M,T,N;
double p[1010][35],p1[1010],pn[1010];
double dp[35][35];

int main(void)
{
while(scanf("%d %d %d",&M,&T,&N),M!=0||T!=0||N!=0)
{
for(int i=1;i<=T;++i)
for(int j=1;j<=M;++j)
scanf("%lf",p[i]+j);
double ans = 1;
for(int i=1;i<=T;++i)//算出每队至少做出来一题的概率
{
double tmp = 1;
for(int j=1;j<=M;++j)
tmp *= (1-p[i][j]);
ans *= (1-tmp);
}
dp[0][0] = 1;
for(int i=1;i<=T;++i)
{
for(int j=1;j<=M;++j)
for(int k=0;k<=j;++k)
{
if(j==k)
{
dp[j][k] = dp[j-1][k-1]*p[i][j];
}
else if(k==0)
{
dp[j][0] = dp[j-1][0]*(1-p[i][j]);
}
else
{
dp[j][k] = dp[j-1][k]*(1-p[i][j])+dp[j-1][k-1]*p[i][j];
}
}
pn[i] = 0;
for(int ii=1;ii<N;++ii)
pn[i] += dp[M][ii];
}
double tmp = 1;
for(int i=1;i<=T;++i)
{
tmp *= pn[i];
}
ans -= tmp;
printf("%.3lf\n",ans);
}

return 0;
}


         for(int k=0;k<=j;++k)

         {

             if(j==k)

             {

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

             }

             else if(k==0)

             {

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

             }

             else

             {

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

             }

         }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: