您的位置:首页 > 其它

poj 2151 Check the difficulty of problems(概率dp)

2013-08-21 16:44 429 查看
poj double 就得交c++,我交G++错了一次

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

题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率

问 每队至少解出一题且冠军队至少解出N道题的概率。

每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2

设dp[i][j][k]表示第i个队在前j道题中解出k道的概率

则:

dp[i][j][k]=dp[i][j-1][k-1]*p[j][k]+dp[i][j-1][k]*(1-p[j][k]);

先初始化算出dp[i][0][0]和dp[i][j][0];

设s[i][k]表示第i队做出的题小于等于k的概率

则s[i][k]=dp[i][M][0]+dp[i][M][1]+``````+dp[i][M][k];

则每个队至少做出一道题概率为P1=(1-s[1][0])*(1-s[2][0])*```(1-s[T][0]);

每个队做出的题数都在1~N-1的概率为P2=(s[1][N-1]-s[1][0])*(s[2][N-1]-s[2][0])*```(s[T][N-1]-s[T][0]);

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<iomanip>
#include<cmath>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

double dp[2010][100][100],s[2010][100],p[2010][100];
int main()
{
int m,n,t,i,j,k;
double p1,p2;
while(cin>>m>>t>>n)
{
if(m==0&&n==0&&t==0)
break;
for(i=1; i<=t; i++)
for(j=1; j<=m; j++)
cin>>p[i][j];
for(i=1; i<=t; i++)
{
dp[i][0][0]=1;
for(j=1; j<=m; j++)
dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j]);
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]);
s[i][0]=dp[i][m][0];
for(k=1; k<=m; k++)
s[i][k]=s[i][k-1]+dp[i][m][k];
}
p1=1; p2=1;
for(i=1; i<=t; i++)
{
p1*=(1-s[i][0]);
p2*=(s[i][n-1]-s[i][0]);
}
printf("%.3lf\n",p1-p2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: