poj 2151 Check the difficulty of problems

题目链接:poj 2151 Check the difficulty of problems


背包dp,用到概率的一点知识


dp[ T ][ i ] 表示第T个人解决i个题目的概率,然后答案就是 每个人至少解决1个题的概率相乘 - 每个人都解决1个题目但是小于n的概率相乘

开始我用的是G++交的wa了,找了半天也没找出错误,用C++交就过了,无语……


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

double p[1010][31],dp[1010][31];

int main()
{
    int m,T,n;
    while(scanf("%d%d%d",&m,&T,&n)==3)
    {
        if(!n&&!T&&!m) break;
        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]=1;
            for(int j=1;j<=m;j++)
            for(int r=m-1;r>=0;r--)
            {
                double pre=dp[i][r];
                dp[i][r]=0;
                dp[i][r+1]+=pre*p[i][j],dp[i][r]+=pre*(1-p[i][j]);
            }
        }
        /*for(int i=1;i<=T;i++)
        {
            for(int j=0;j<=m;j++)
              cout<<dp[i][j]<<" ";
            cout<<endl;
        }*/
        double ans1=1,ans2=1;
        for(int i=1;i<=T;i++)
        {
            double tmp1=0,tmp2=0;
            for(int j=m;j>=1;j--)
            {
                tmp1+=dp[i][j];
                if(j>=n) tmp2+=dp[i][j];
            }
            ans1*=tmp1;
            ans2*=(tmp1-tmp2);
        }
        printf("%.3lf\n",ans1-ans2);
    }
    return 0;
}


你可能感兴趣的:(poj 2151 Check the difficulty of problems)