pku 2151 Check the difficulty of problems 概率+dp

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

题意是:对于acm出题,出m到题,你要保证每支队伍至少做出一道题目,并且冠军队伍要做出至少n道题目;

我们只要求出所有队伍至少解决一道题目的概率(pa),和所有队伍解决出(1--n -1)到题目的概率pb,然后pa-pb就是我们所需要的答案了。。

dp[i][j][k] 表示第i支队伍,在前j道题目中,解决了k道题目的概率;

则有dp[i][j][k] = dp[i][j - 1][k]*(1 - p[i][j]) + dp[i][j - 1][k - 1] *p[i][j];分第j道题目做出来与没做出来两种情况

dp[i][j][0] = dp[i][j - 1]*(1 - p[i][j]);//一道都没做出来

dp[i][j][j] = dp[i][j - 1][j - 1]*p[i][j]//每到都做出来了

View Code
#include <iostream>
#include <cstring>
#include <cstdio>
#define T 1007
#define M 32
using namespace std;

double dp[T][M][M],p[T][M];
int main()
{
int i,j,t,m,n,k;
while (~scanf("%d%d%d",&m,&t,&n))
{
if (!t && !m && !n) break;
for (i = 1; i <= t; ++i)
{
for (j = 1; j <= m; ++j)
{
scanf ("%lf",&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]);
dp[i][j][j] = dp[i][j - 1][j - 1] * p[i][j];
}
}
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]);
}
}
}
double pa = 1.0,pb = 1.0;
for (i = 1; i <= t; ++i)
{
pa *= (1 - dp[i][m][0]);
}
for (i = 1; i <= t; ++i)
{
double sum = 0;
for (k = 1; k < n; ++k)
{
sum += dp[i][m][k];
}
pb *= sum;
}
printf("%.3f\n",pa - pb);
}
return 0;
}



posted @ 2012-03-29 16:36  E_star  阅读(215)  评论(0编辑  收藏  举报