您的位置:首页 > 其它

poj 2151 概率DP

2017-07-07 16:09 176 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: