POJ 2151 Check the difficulty of problems
这道题是一道概率DP题,好难啊!!!
题目大体是这个意思:
ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率
问 每队至少解出一题且冠军队至少解出N道题的概率(冠军可以并列)。
看题解看懂的,表示大牛们真的好强。因为冠军不一定有多少,所以这题需要转化为:
求每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2。

再次感谢大牛可以让我盗图,本事不够只能这样了,慢慢学吧。
下面是代码:
#include <stdio.h>
#include <string.h>
double p[1003][33],dp[1003][33][33],s[1003][33];
int main()
{
int m,t,n;
while(scanf("%d%d%d",&m,&t,&n),m||t||n)
{
int i,j,k;
double p1=1,p2=1,temp;
for(i=1; i<=t; i++)
{
for(j=1; j<=m; j++)
{
scanf("%lf",&p[i][j]);
}
}
memset(dp,0.0,sizeof(dp));
memset(s,0.0,sizeof(s));
for(i=1; i<=t; i++) //逐队枚举
{
dp[i][0][0]=1.0;
for(j=1; j<=m; j++)
{
dp[i][j][0]=dp[i][j-1][0]*(1-p[i][j]); //初始化每队前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]);
/**第I队当解到第J题时解出K个题的概率是解前J-1个题时解出K-1个的概率乘以解出第
J题的概率加上解前J-1个题时解出K个的概率乘以第J个题没解出的概率*/
}
}
s[i][0]=dp[i][m][0];//最后第I队解0个题的概率是dp[i][m][0];及第I队做M题做出0道的概率。
for(k=1; k<=m; k++)
{
s[i][k]=s[i][k-1]+dp[i][m][k];
//第I队解出K道题的概率是第I队解出K-1道题的概率加上及第I队做M题做出K道的概率。
}
}
//p1为每队均至少做一题的概率,p2为每队做题数均在1到N-1之间的概率。
for(i=1; i<=t; i++)
{
p1*=(s[i][m]-s[i][0]);
}
for(i=1; i<=t; i++)
{
p2*=(s[i][n-1]-s[i][0]);
}
printf("%.3lf\n",p1-p2);
}
return 0;
}

浙公网安备 33010602011771号