Check the difficulty of problems--POJ 2151
1、题目类型:DP、概率论。
2、解题思路:题意,一次比赛中,共M道题,T个队,p[i][j]表示队i解出题j的概率;问每队至少解出一题且冠军队至少解出N道题的概率。步骤,(1)将输入转换为map[i][j]表示第i队求解第j题的概率;(2)根据map[][]建立DP[i][j][k]表示第 i 队在前 j 题中求解 k 题的概率;(3)所有队求解大于1题的概率减去所有队都没有求解N题的概率即为结果。
3、注意事项:各个队的解题为独立概率事件。
4、实现方法:
#include<iostream>
using namespace std;
int M,T,N;
double map[1010][32];
double dp[1010][32][32];
double ans;
void DP()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(i=1;i<=T;i++)
{
dp[i][1][1]=map[i][1];
dp[i][1][0]=1-map[i][1];
}
for(i=1;i<=T;i++)
for(j=2;j<=M;j++)
for(k=0;k<=M;k++)
dp[i][j][k]=dp[i][j-1][k-1]*map[i][j]+dp[i][j-1][k]*(1-map[i][j]);
}
void Solution()
{
int i,j;
double p1=1,p2=1,p3;
for(i=1;i<=T;i++)
p1*=(1-dp[i][M][0]);
for(i=1;i<=T;i++)
{
p3=0;
for(j=1;j<N;j++)
p3+=dp[i][M][j];
p2*=p3;
}
ans=p1-p2;
}
int main()
{
int i,j;
while(cin>>M>>T>>N )
{
if(M==0 && T==0 && N==0)
break;
memset(map,0,sizeof(map));
ans=0;
for(i=1;i<=T;i++)
for(j=1;j<=M;j++)
{
cin>>map[i][j];
}
DP();
Solution();
printf("%.3f\n",ans);
}
return 0;
}