http://poj.org/problem?id=2151
概率还是不行。简单的一个式子还是能够推的
可是方程构造以及思路 全然不行啊....
參考小优的博客http://blog.csdn.net/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; }