您的位置:首页 > 其它

POJ 2151 Check the difficulty of problems DP

2011-08-24 22:37 423 查看
题意:有M道题目,每支队伍至少做出一道题,并且至少有一只对队伍做出n道题。输出概率。

题解:
『算法』

设a[i][j][k]表示第i队在前j道题中共解出k道题的概率,易得a[i][j][k]有如下递推

关系(另需考虑边界条件):

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

设s[i][j]表示a[i][M][0] + a[i][M][1] + ... + a[i][M][j]

问题的解可以转化为:每队均至少做一题的概率(用P1表示)减去每队做题数均在1到N-1

之间的概率(用P2表示)。

P1 = (s[1][M] - s[1][0])*(s[2][M]-s[2][0])*...*(s[T][M]-s[T][0])

P2 = (s[1][N-1] - s[1][0])*(s[2][N-1]-s[2][0])*...*(s[T][N-1]-s[T][0])

『算法复杂度』

O(T*M^2)
#include <iostream>
using namespace std;
#define M 35
#define T 1005
double p[T][M], dp[T][M][M];
int main()
{
int m, t, n, i, j, k;
double p1, p2, temp;
//freopen("a.txt","r",stdin);
while ( scanf("%d%d%d",&m,&t,&n) && (m+t+n) )
{
memset(p,0,sizeof(p));
memset(dp,0,sizeof(dp));
for ( i = 1; i <= t; i++ )
{
for ( j = 1; j <= m; j++ )
{
scanf("%lf",&p[i][j]);
if ( j == 1 )
{
dp[i][j][0] = 1.0 - p[i][j];
dp[i][j][1] = p[i][j];
}
else
{
for ( k = 0; 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];
}
}
}
p1 = p2 = 1;
for ( i = 1; i <= t; i++ )
{
p1 *= ( 1 - dp[i][m][0] );
temp = 0;
for ( j = 1; j < n; j++ )
temp += dp[i][m][j];
p2 *= temp;
}
printf("%.3lf\n", p1 - p2 );
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法