poj2151 Check the difficulty of problems(概率dp)

来源:互联网 发布:手机淘宝怎么写评论 编辑:程序博客网 时间:2024/05/16 02:05

poj2151

题目

有t支队伍,m道题,给你每支队伍做出每道题的概率,求所有队伍至少做出1道,冠军队伍至少做出n道的概率

思路

dp[i][j][k]表示第i支队伍做了j道,做出k道的概率,通过递推可以得出。
“由于冠军队可以不止一队,即允许存在并列冠军”
最终答案就是:每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2

代码

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;int m,t,n;double p[1010][35];double dp[1010][35][35];int main(){    while(scanf("%d%d%d",&m,&t,&n)!=EOF&&(m+t+n))    {        for(int i=1; i<=t; i++)            for(int j=1; j<=m; j++)                scanf("%lf",&p[i][j]);        memset(dp,0,sizeof(dp));        for(int i=1; i<=t; i++)        {            dp[i][0][0]=1;            for(int j=1; j<=m; j++)                for(int k=0; k<=j; k++)                {                    dp[i][j][k]=dp[i][j-1][k]*(1-p[i][j]);                    if(k!=0)                        dp[i][j][k]+=dp[i][j-1][k-1]*p[i][j];                }        }        double temp1,temp2;        temp2=1;        for(int i=1; i<=t; i++)        {            temp1=0;            for(int j=1; j<=m; j++)                temp1+=dp[i][m][j];            temp2*=temp1;        }        double ans=temp2;        temp2=1;        for(int i=1; i<=t; i++)        {            temp1=0;            for(int j=1; j<n; j++)                temp1+=dp[i][m][j];            temp2*=temp1;        }        printf("%.3lf\n",ans-temp2);    }    return 0;}
0 0
原创粉丝点击