http://poj.org/problem?id=2151
概率还是不行,简单的一个式子还是可以推的
但是方程构造以及思路 完全不行啊....
参考小优的博客http://blog.youkuaiyun.com/lyy289065406/article/details/6648579
感觉思路比较好的
1、dp三维设定的意义
2、s[i][j]推出Ans 好精妙
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
const int MAXT = 1000+5;
const int MAXN = 35;
int n,m,t;
double p[1000+5][MAXN];
double dp[MAXT][MAXN][MAXN];
double s[MAXT][MAXN];
double solve()
{
CL(dp,0);CL(s,0);
for(int i=1;i<=t;i++)dp[i][0][0]=1.0;
for(int i=1;i<=t;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j][0]=1.0;
for(int k=1;k<=j;k++)dp[i][j][0]*=(1-p[i][k]);
for(int 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(int j=1;j<=m;j++)
for(int k=0;k<=j;k++)
s[i][j]+=dp[i][m][k]; //第i支队在前m题做出0~j题的概率
}
double ret1=1.0,ret2=1.0;
for(int i=1;i<=t;i++)
{
ret1*=(s[i][m]-s[i][0]);
ret2*=(s[i][n-1]-s[i][0]);
}
return ret1-ret2;
}
int main()
{
//IN("poj2151.txt");
while(~scanf("%d%d%d",&m,&t,&n) && m+t+n)
{
for(int i=1;i<=t;i++)
for(int j=1;j<=m;j++)
scanf("%lf",&p[i][j]);
printf("%.3lf\n",solve());
}
return 0;
}