poj 2151 概率DP

http://poj.org/problem?id=2151

概率还是不行。简单的一个式子还是能够推的

可是方程构造以及思路  全然不行啊....

參考小优的博客http://blog.csdn.net/lyy289065406/article/details/6648579

感觉思路比較好的

1、dp三维设定的意义

2、s[i][j]推出Ans  好精妙


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)

const int MAXT = 1000+5;
const int MAXN = 35;

int n,m,t;
double p[1000+5][MAXN];
double dp[MAXT][MAXN][MAXN];
double s[MAXT][MAXN];

double solve()
{
    CL(dp,0);CL(s,0);
    for(int i=1;i<=t;i++)dp[i][0][0]=1.0;

    for(int i=1;i<=t;i++)
    {
        for(int j=1;j<=m;j++)
        {
            dp[i][j][0]=1.0;
            for(int k=1;k<=j;k++)dp[i][j][0]*=(1-p[i][k]);
            for(int 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]);
            }

        }
        s[i][0]=dp[i][m][0];
        for(int j=1;j<=m;j++)
            for(int k=0;k<=j;k++)
                s[i][j]+=dp[i][m][k];      //第i支队在前m题做出0~j题的概率
    }

    double ret1=1.0,ret2=1.0;
    for(int i=1;i<=t;i++)
    {
        ret1*=(s[i][m]-s[i][0]);
        ret2*=(s[i][n-1]-s[i][0]);
    }
    return ret1-ret2;
}

int main()
{
    //IN("poj2151.txt");
    while(~scanf("%d%d%d",&m,&t,&n) && m+t+n)
    {
        for(int i=1;i<=t;i++)
            for(int j=1;j<=m;j++)
                scanf("%lf",&p[i][j]);
        printf("%.3lf\n",solve());
    }
    return 0;
}


posted @ 2017-07-07 16:09  zhchoutai  阅读(117)  评论(0编辑  收藏  举报