poj2151 Check the difficulty of problems

Check the difficulty of problems
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 6685 Accepted: 2907

Description

Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually expect the contest result satisfy the following two terms: 
1. All of the teams solve at least one problem. 
2. The champion (One of those teams that solve the most problems) solves at least a certain number of problems. 

Now the organizer has studied out the contest problems, and through the result of preliminary contest, the organizer can estimate the probability that a certain team can successfully solve a certain problem. 

Given the number of contest problems M, the number of teams T, and the number of problems N that the organizer expect the champion solve at least. We also assume that team i solves problem j with the probability Pij (1 <= i <= T, 1<= j <= M). Well, can you calculate the probability that all of the teams solve at least one problem, and at the same time the champion team solves at least N problems? 

Input

The input consists of several test cases. The first line of each test case contains three integers M (0 < M <= 30), T (1 < T <= 1000) and N (0 < N <= M). Each of the following T lines contains M floating-point numbers in the range of [0,1]. In these T lines, the j-th number in the i-th line is just Pij. A test case of M = T = N = 0 indicates the end of input, and should not be processed.

Output

For each test case, please output the answer in a separate line. The result should be rounded to three digits after the decimal point.

Sample Input

2 2 2
0.9 0.9
1 0.9
0 0 0

Sample Output

0.972
一个概率dp的题插在了哈希里.......

这道题的意思就是说现在有T只队伍,要测试的题目M然后是对冠军队伍的期望最少要解出的题目。然后就是求每只队伍至少求出一题,冠军队伍至少求出N题事件发生的概率。

不难想到,我们可以计算出,每只队伍做出1-m(用P1表示)个题的概率,然后相乘,这样就能确保结果是每支队伍都能解出1-m个题,然后还有个约束条件就是冠军队至少要解出N题,也就是说我们应当去除每支队伍都求解出1-(n-1)(用P2表示)道题的情况,这样就可以确保至少有一只队伍是求解出n道题以上的,并且其余的队伍也是至少求解出1题。

然后问题就是怎么求解出P1和P2。

我们可以先求解出每支队伍的p1和p2,然后直接相乘就可以。

然后怎么求解p1和p2。我们分别用s1,s2代替。


借用一下别人的图片,可以看的更明白一些,然后我们可以去掉第一维。

递推式就是dp[j][k]=dp[j-1][k-1]*p[i][j]+dp[j-1][k]*(1-p[i][j]);

最后计算出,前M道题分别解出1、2、3、.....M道题的概率。相加之后就得到了s1,然后P1累乘

对于P2也是一样,到N-1,得到s2,P2累乘,最后相减即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int MAXN=1000+5;
const int inf=0x3f3f3f;
int m,t,n;
double dp[35][35];
double p1,p2;
double p[MAXN][35];
double s1,s2;
int main()
{
    while(~scanf("%d%d%d",&m,&t,&n))
    {
        if(!m&&!t&&!n)break;
        int i,j,k;
        for(i=1; i<=t; ++i)
            for(j=1; j<=m; ++j)scanf("%lf",&p[i][j]);
            memset(dp,0,sizeof(dp));//初始化dp数组
        p1=1.0,p2=1.0;//p1用来记录每个队伍做1-m个题的概率,p2用来记录每个队伍做1~(n-1)个题目的概率
        for(i=1; i<=t; ++i)
        {
            dp[0][0]=1.0;//前0道题做出0个题的概率自然是0
            for(j=1;j<=m;++j)dp[j][0]=dp[j-1][0]*(1-p[i][j]);//前j个题做出0道题的概率

            for(j=1;j<=m;++j)//计算每个队伍的dp值
            {
                for(k=1;k<=j;++k)
                {
                    dp[j][k]=dp[j-1][k-1]*p[i][j]+dp[j-1][k]*(1-p[i][j]);
                }
            }
            s1=0.0,s2=0.0;
            for(j=1;j<=m;++j)s1+=dp[m][j];//记录这只队伍做1-m个题的概率
            for(j=1;j<n;++j)s2+=dp[m][j];//和1-(n-1)个题的概率;
            p1*=s1;
            p2*=s2;
        }
         printf("%.3f\n",p1-p2);

    }
    return 0;
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值