poj 2151 概率dp(求概率)&&poj3071全概率公式

/*
思路:http://www.cnblogs.com/rainydays/archive/2011/07/01/2095913.html
题意:在acm比赛中,n题,t队。给出每个队做对每题的概率,问每队至少对一题,至少有一队做对至少m题的概率

分析:dp,f[i][j]表示第i个队伍做对第j题的概率。g[i][j][k]表示第i个队伍对于前j题而言做对k道的概率。

g[i][j][k] = g[i][j - 1][k - 1] * (f[i][j]) + g[i][j - 1][k] * (1 - f[i][j]);

有了所有的g,我们就可以求出每个队至少做对1题的概率:ans *= 1 - g[i][n][0];

再减去每个队都只做对1~m-1题的概率(把每个队做对1~m-1题的概率加和,并把各队结果相乘)
*/
#include
#include
#define N 1100
double  dp[N][40][40];
double p[N][40];
int main()
{
    int m,n,t,i,j,k;
    double pa,pab;
    while(scanf("%d%d%d",&m,&t,&n),m||t||n)
    {
        for(i=1; i<=t; i++)
            for(j=1; j<=m; j++)
                scanf("%lf",&p[i][j]);
        memset(dp,0,sizeof(dp));
        for(i=1; i<=t; i++)//初始化
        {
            dp[i][0][0]=1;
            for(j=1; j<=m; j++)
            {
                dp[i][j][0]=1;
                for(k=1; k<=j; k++)
                    dp[i][j][0]*=(1-p[i][k]);
            }
        }
        for(i=1; i<=t; i++)
            for(j=1; j<=m; j++)
                for(k=1; k<=j; k++) {
                    dp[i][j][k]=dp[i][j-1][k-1]*p[i][j]+dp[i][j-1][k]*(1-p[i][j]);
           // printf("%d %d %d %lf\n",i,j,k,dp[i][j][k]);
            }
        pa=1;
        for(i=1; i<=t; i++)
        {
            double ph=0;
            for(j=1; j<=m; j++)
                ph+=dp[i][m][j];
            pa*=ph;
        }
        pab=1;
        for(i=1; i<=t; i++)
        {
            double ph=0;
            for(j=1; j<=n-1; j++)
                ph+=dp[i][m][j];
            pab*=ph;
        }
        printf("%.3f\n",pa-pab);
    }
    return 0;
}
  poj3071  for(i=0;i<(1<

你可能感兴趣的:(编程,dp,stl+杂碎知识+概率算法)