poj 2151 概率dp

//poj 2151 概率dp

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 using namespace std;
 6 double dp[33][33];
 7 int M, T, N;    //problem, team, least
 8 double p[1010][33];
 9 int main()
10 {
11     int i, j, k;
12     while(scanf("%d%d%d", &M, &T, &N) && (M || T || N)) {
13         for(i = 1; i <= T; ++i)
14             for(j = 1; j <= M; ++j)
15                 scanf("%lf", &p[i][j]);
16         double res_1 = 1, res_2 = 1;    //所有队伍都解出一题以上的概率,所有队伍都没解到超过 N 道的概率
17         for(i = 1; i <= T; ++i) {
18             dp[0][0] = 1;
19             for(j = 1; j <= M; ++j) {
20                 for(k = 0; k <= j && k < N; ++k) {
21                     if(k >= 1)
22                         dp[j][k] = dp[j - 1][k] * (1 - p[i][j]) + dp[j - 1][k - 1] * p[i][j];
23                     else
24                         dp[j][k] = dp[j - 1][k] * (1 - p[i][j]);
25                 }
26             }
27             res_1 *= (1 - dp[M][0]);
28             double tmp = 0;
29             for(k = 1; k < N; ++k)
30                 tmp += dp[M][k];
31             res_2 *= tmp;
32         }
33         printf("%.3f\n",res_1 - res_2);
34     }
35 }

//优化下空间

 1 #include "iostream"
 2 #include "cstring"
 3 #include "algorithm"
 4 #include "cstdio"
 5 using namespace std;
 6 int M, T, N; //problem, team, least
 7 double dp[35][35];
 8
 9 int main()
10 {
11     int i, j, k;
12     double p, res_1, res_2; //所有队伍都解出一题以上的概率,所有队伍都没解到超过 N 道的概率
13     while(scanf("%d%d%d", &M, &T, &N) && (N || T || M)) {
14         res_1 = res_2 = 1;
15         for(i = 1; i <= T; ++i) {
16             dp[0][0] = 1;
17             for(j = 1; j <= M; ++j) {
18                 scanf("%lf", &p);
19                 for(k = 0; k <= j && k < N; ++k) {
20                     if(k >= 1)
21                         dp[j][k] = dp[j - 1][k] * (1 - p) + dp[j - 1][k - 1] * p;
22                     else
23                         dp[j][k] = dp[j - 1][k] * (1 - p);
24                 }
25             }
26             res_1 *= (1 - dp[M][0]);
27             double tmp = 0;
28             for(k = 1; k<N; ++k)
29                 tmp += dp[M][k];
30             res_2 *= tmp;
31         }
32         printf("%.3f\n", res_1 - res_2);
33     }
34 }
时间: 2024-10-11 18:12:40

poj 2151 概率dp的相关文章

Check the difficulty of problems - poj 2151 (概率+DP)

有 T(1<T<=1000) 支队伍和 M(0<M<=30) 个题目,已知每支队伍 i 解决每道题目 j 的的概率 p[i][j],现在问:每支队伍至少解决一道题,且解题最多的队伍的题目数量不少于 N(0<N<=M) 的概率是多少? p[i][j]表示第i个队伍做对第j题的概率.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])

POJ 3701 概率DP

给定2^n 支足球队进行比赛,n<=7. 队伍两两之间有一个获胜的概率,求每一个队伍赢得最后比赛的概率是多少? 状态其实都是很显然的,一开始觉得这个问题很难啊,不会.dp[i][j] 表示第i支队伍赢得前j轮比赛的概率.(这个题目处理区间的时候比较恶心,小心点即可). 1:   2: #include <iostream> 3: #include <cstdio> 4: #include <cstring> 5: #include <map> 6: #

poj 2096 (概率DP)

http://poj.org/problem?id=2096 概率DP: 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 double dp[1003][1003]; 5 int main() 6 { 7 int n,s,i,j; 8 cin>>n>>s; 9 for (i=n;i>=0;i--) 10 { 11 for (j=s;j>=0;j--) 12 { 13

poj 3744 概率dp+矩阵快速幂

题意:在一条布满地雷的路上,你现在的起点在1处.在N个点处布有地雷,1<=N<=10.地雷点的坐标范围:[1,100000000]. 每次前进p的概率前进一步,1-p的概率前进1-p步.问顺利通过这条路的概率.就是不要走到有地雷的地方. 设dp[i]表示到达i点的概率,则 初始值 dp[1]=1. 很容易想到转移方程: dp[i]=p*dp[i-1]+(1-p)*dp[i-2]; 但是由于坐标的范围很大,直接这样求是不行的,而且当中的某些点还存在地雷. N个有地雷的点的坐标为 x[1],x[2

poj 3071 概率DP 位运算

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit Status Practice POJ 3071 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2n. In each round of the tournament, all tea

poj 3744 概率dp 矩阵快速幂优化

一位童子兵要穿过一条路,路上有些地方放着地雷.这位童子兵非常好玩,走路一蹦一跳的.每次他在 i 位置有 p 的概率走一步到 i+1 ,或者 (1-p) 的概率跳一步到 i+2.童子兵初始在1位置,求他安全通过这条道路的概率. 以所在位置为状态,dp[i] 表示在位置 i 的安全的概率. dp[i] = p * dp[i-1] + (1 - p) * dp[i-2]; // i 位置没有地雷 但是题目数据的范围是 10^8 这样dp的话会 TLE. 想想可以用矩阵快速幂优化.简单退出矩阵是 |p

Scout YYF I POJ - 3744(概率dp + 矩阵快速幂)

题意: 一条路上有n个地雷,你从1开始走,单位时间内有p的概率走一步,1-p的概率走两步,问安全通过这条路的概率 解析: 很容易想到 dp[i] = p * dp[i-1] + (1 - p) * dp[i]; 然而...t,但这个式子明显可以用矩阵快速幂加个氮气一下加速一下... 把所有的点输入之后 sort一下,那么就能把这条路分成很多段 每一段以地雷为分界线 1 - x[0]  x[0]+1 - x[1]  x[1]+1 - x[2] ````````` 然后求出安全通过每一段的概率  

poj 3071 概率dp

//分析:明显的树形关系,题目描述的是一棵高 n + 1的完全二叉树,则 dp[树层号][team号](规定最底层为 0 层,层数朝节点的方向依次递增),推一下就好了 //稍微需要想一下的是比赛双方的选取,下面给出两种方法 //#1 枚举起点划分team区间 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm"

POJ 2151 Check the difficulty of problems (概率dp)

题意:给出m.t.n,接着给出t行m列,表示第i个队伍解决第j题的概率. 现在让你求:每个队伍都至少解出1题,且解出题目最多的队伍至少要解出n道题的概率是多少? 思路:求补集. 即所有队伍都解出题目的概率,减去所有队伍解出的题数在1~n-1之间的概率 这里关键是如何求出某个队伍解出的题数在1~n-1之间的概率,采用dp的方法: 用p(i,j)表示前i道题能解出j道的概率,有p(i,j)=p(i-1,j)*(1-p(i))+p(i-1,j-1)*p(i)p(i)表示解出第i题的概率. #inclu