[POJ2151]Check the difficulty of problems (概率dp)
2015-06-04 23:30
267 查看
题目链接:http://poj.org/problem?id=2151
题目大意:有M个题目,T支队伍,第i个队伍做出第j个题目的概率为Pij,问每个队伍都至少做出1个题并且至少有一个队伍做出N题的概率。
先定义状态dp[i][j][k],代表第i支队伍从前j个题目里正好做出k题的概率。
有:dp[i][j][k] = dp[i][j-1][k]*(1-p[i][j]) + dp[i][j-1][k-1]*p[i][j];
然后设f[i]为前i支队伍里,每队至少做出一个题并且至少有一个队伍做出N题的概率。
那么f[i] = f[i-1]*(第i支队伍做出不少于1题的概率) + (1-f[i-1]-存在队伍没做出题的概率)*(第i支队伍做了不少于N题的概率)
上面这个是个全概率公式
于是乎:
题目大意:有M个题目,T支队伍,第i个队伍做出第j个题目的概率为Pij,问每个队伍都至少做出1个题并且至少有一个队伍做出N题的概率。
先定义状态dp[i][j][k],代表第i支队伍从前j个题目里正好做出k题的概率。
有:dp[i][j][k] = dp[i][j-1][k]*(1-p[i][j]) + dp[i][j-1][k-1]*p[i][j];
然后设f[i]为前i支队伍里,每队至少做出一个题并且至少有一个队伍做出N题的概率。
那么f[i] = f[i-1]*(第i支队伍做出不少于1题的概率) + (1-f[i-1]-存在队伍没做出题的概率)*(第i支队伍做了不少于N题的概率)
上面这个是个全概率公式
于是乎:
///#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <map> #include <set> #include <bitset> #include <cmath> #include <numeric> #include <iterator> #include <iostream> #include <cstdlib> #include <functional> #include <queue> #include <stack> #include <string> #include <cctype> using namespace std; #define PB push_back #define MP make_pair #define SZ size() #define ST begin() #define ED end() #define CLR clear() #define ZERO(x) memset((x),0,sizeof(x)) typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; const double EPS = 1e-8; const int MAX_T = 1111; const int MAX_M = 33; int M,T,N; double p[MAX_T][MAX_M],f[MAX_T],any[MAX_T],dp[MAX_T][MAX_M][MAX_M]; int main(){ while( ~scanf("%d%d%d",&M,&T,&N), M!=0&&T!=0&&N!=0 ) { ZERO(dp); ZERO(f); ZERO(any); for(int i=1;i<=T;i++) { for(int j=1;j<=M;j++) { scanf("%lf",&p[i][j]); } } for(int i=1;i<=T;i++){ dp[i][0][0] = 1.0; for(int j=1;j<=M;j++) { dp[i][j][0] = dp[i][j-1][0]*(1-p[i][j]); } for(int j=1;j<=M;j++){ 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]; } } for(int j=1;j<=M;j++){ for(int k=1;k<=M;k++){ dp[i][j][k] += dp[i][j][k-1]; } } } f[0] = 0.0; any[0] = 1.0; for(int i=1;i<=T;i++){ any[i] = any[i-1]*(1.0-dp[i][M][0]); } for(int i=1;i<=T;i++){ any[i] = 1.0 - any[i]; } any[0] = 0.0; for(int i=1;i<=T;i++){ f[i] = f[i-1]*(dp[i][M][M]-dp[i][M][0]) + (1.0-f[i-1]-any[i-1])*(dp[i][M][M]-dp[i][M][N-1]); } printf("%.3f\n",f[T]); } return 0; }
相关文章推荐
- ospf配置实验
- R4fun之文字竖排
- CMake 使用方法
- 第三章 43,44题
- java第三次实验
- ThinkPHP 3.2 PHPExcel 导入导出文件 第三方类库不能用问题解决
- poj 1847 Tram 【最短路 dijkstra + floyd + spfa】
- Java for LeetCode 149 Max Points on a Line
- 变量(续)
- ActiveMQ入门实例
- Java NIO系列教程(二) Channel
- 第二章第6题
- uva 1593 代码对齐
- LeetCode Unique Paths II(dp)
- 路由表解释
- python 与 c/c++混合编程
- 通过redis的monitor命令排除故障
- 4.22
- ia32问题
- “找一”