Check the difficulty of problems POJ

来源:互联网 发布:php怎么调用接口 编辑:程序博客网 时间:2024/06/15 02:46

题意是给定m道题,t个队伍,求冠军队伍最少做n题的概率


p[i][j]是记录第i队伍做出第j道题的概率。

dp[i][j]记录第o个队伍在前I道题中做出j道题的概率

sum[i][j]记录第i个队伍做出小于等于j道题的概率。

代码如下

#include<cstdio>#include<iostream>#include<cstring>using namespace std;double p[1010][32],dp[1010][32][32],s[1010][32];int m,n,t;//动态规划,计算每个队伍在前i道题中做出j道题的概率void calculate(int o){    dp[o][1][0]=1.0-p[o][1];            dp[o][1][1]=p[o][1];    for(int i=2; i<=m; ++i)        for(int j=0; j<=m&&j<=i; ++j)        {            if(j==0)                dp[o][i][j]=dp[o][i-1][j]*(1-p[o][i]);            else                dp[o][i][j]=dp[o][i-1][j]*(1.0-p[o][i])+dp[o][i-1][j-1]*p[o][i];        }}int main(){    while(cin>>m>>t>>n&&(m+t+n))    {        memset(p,0,sizeof(p));        memset(dp,0,sizeof(dp));        for(int i=1; i<=t; ++i)            for(int j=1; j<=m; ++j)                scanf("%lf",&p[i][j]);        //动态规划,计算每个队伍在前i道题中做出j道题的概率        for(int i=1; i<=t; ++i)            calculate(i);        for(int i=1;i<=t;++i)            s[i][0]=dp[i][m][0];        for(int i=1;i<=t;++i)            for(int j=1;j<=m;++j)                s[i][j]=s[i][j-1]+dp[i][m][j];        double p1=1.0,p2=1.0;        for(int i=1;i<=t;++i)        {            p1*=(s[i][m]-s[i][0]);            p2*=(s[i][n-1]-s[i][0]);        }        printf("%.3f\n",p1-p2);    }}

这里解释一下 p1,p2

p1-p2就是属于p1的但不属于p2的事情的概率,p1是每个队都做出不小于一道题的概率,p2是每个队都做出1-n-1道题的概率,那么p1-p2就是在每个队做出不少于一道题的前提下有队伍做出不少于n道的概率。