poj 2151 Check the difficulty of problems

   需要一定的概率基础,然后加上一定的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];
             }
         }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值