POJ 2151 Check the difficulty of problems:概率dp【至少】

题目链接:http://poj.org/problem?id=2151

题意:

  一次ACM比赛,有t支队伍,比赛共m道题。

  第i支队伍做出第j道题的概率为p[i][j].

  问你所有队伍都至少做出一道,并且有队伍做出至少n道的概率。

题解:

  关于【至少】问题的表示。

  

  对于每一支队伍:

    mst[i][j] = P(第i支队伍做出至多j道题)

    则 P(第i支队伍做出至少j道题) = 1 - mst[i][j-1]

  

  对于所有队伍:

    P(所有队伍至少答出一题) = ∏ (1 - mst[i][0])

    P(所有队伍答题数在1到n-1) = ∏ (mst[i][n-1] - mst[i][0])

    所以答案:

    P(所有队伍至少答出一题,且有队伍做出至少n道) = P(所有队伍至少答出一题) - P(所有队伍答题数在1到n-1)

  所以求mst数组好啦~~~

  dp[i][j][k] = probability

  i:第i支队伍

  j:考虑到前j道题(包含j)

  k:恰好做出k道

  所以 mst[i][j] = sigma(dp[i][m][0 to j])

  怎么求dp数组呢:

    转移:dp[i][j][k] = dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j])

    边界:dp[i][0][0] = 1, others = 0

  所以这道题:先求dp,再求mst,最后统计ans。

AC Code:

  1 // state expression:
  2 // dp[i][j][k] = probability
  3 // i: ith team
  4 // j: jth question and before
  5 // k: solved k questions
  6 // mst[i][j]
  7 // i: ith team
  8 // j: all the teams solved at most j questions
  9 //
 10 // find the answer:
 11 // P(all 1 to m) - P(all 1 to n-1)
 12 //
 13 // transferring:
 14 // dp[i][j][k] = dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j])
 15 //
 16 // boundary:
 17 // dp[i][0][0] = 1
 18 // others = 0
 19 //
 20 // calculate:
 21 // mst[i][j] = sigma dp[i][m][0 to j]
 22 // P1 = pi (1 - mst[i][0])
 23 // P2 = pi (mst[i][n-1] - mst[i][0])
 24 //
 25 // step:
 26 // 1) cal dp
 27 // 2) cal mst
 28 // 3) cal ans
 29 #include <iostream>
 30 #include <stdio.h>
 31 #include <string.h>
 32 #define MAX_T 1005
 33 #define MAX_N 35
 34 #define MAX_M 35
 35
 36 using namespace std;
 37
 38 int n,m,t;
 39 double p1,p2;
 40 double p[MAX_T][MAX_M];
 41 double dp[MAX_T][MAX_M][MAX_M];
 42 double mst[MAX_T][MAX_M];
 43
 44 void read()
 45 {
 46     for(int i=1;i<=t;i++)
 47     {
 48         for(int j=1;j<=m;j++)
 49         {
 50             cin>>p[i][j];
 51         }
 52     }
 53 }
 54
 55 void cal_dp()
 56 {
 57     memset(dp,0,sizeof(dp));
 58     for(int i=1;i<=t;i++)
 59     {
 60         dp[i][0][0]=1;
 61         for(int j=1;j<=m;j++)
 62         {
 63             for(int k=0;k<=m;k++)
 64             {
 65                 if(k-1>=0) dp[i][j][k]+=dp[i][j-1][k-1]*p[i][j];
 66                 dp[i][j][k]+=dp[i][j-1][k]*(1-p[i][j]);
 67             }
 68         }
 69     }
 70 }
 71
 72 void cal_mst()
 73 {
 74     // mst[i][j] = sigma dp[i][m][0 to j]
 75     memset(mst,0,sizeof(mst));
 76     for(int i=1;i<=t;i++)
 77     {
 78         for(int j=0;j<=m;j++)
 79         {
 80             for(int k=0;k<=j;k++)
 81             {
 82                 mst[i][j]+=dp[i][m][k];
 83             }
 84         }
 85     }
 86 }
 87
 88 void cal_ans()
 89 {
 90     // P1 = pi (1 - mst[i][0])
 91     // P2 = pi (mst[i][n-1] - mst[i][0])
 92     p1=1.0;
 93     p2=1.0;
 94     for(int i=1;i<=t;i++)
 95     {
 96         p1*=(1-mst[i][0]);
 97         p2*=(mst[i][n-1]-mst[i][0]);
 98     }
 99 }
100
101 void solve()
102 {
103     cal_dp();
104     cal_mst();
105     cal_ans();
106 }
107
108 void print()
109 {
110     printf("%.3f\n",p1-p2);
111 }
112
113 int main()
114 {
115     while(cin>>m>>t>>n)
116     {
117         if(m==0 && t==0 && n==0) break;
118         read();
119         solve();
120         print();
121     }
122 }
时间: 2024-08-08 03:18:26

POJ 2151 Check the difficulty of problems:概率dp【至少】的相关文章

[ACM] POJ 2151 Check the difficulty of problems (概率+DP)

Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4748   Accepted: 2078 Description Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually exp

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

题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 k 个题的概率,sum[i][j] 表示第 i 个队伍,做出 1-j 个题的概率,ans1等于, T个队伍,至少解出一个题的概率,ans2 表示T个队伍,至少解出一个题,但不超过N-1个题的概率,最后用ans1-ans2即可. 代码如下: #pragma comment(linker, "/STA

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

题目链接:http://poj.org/problem?id=2151 Description Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually expect the contest result satisfy the following two terms: 1. All of the teams solv

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

poj 2151 Check the difficulty of problems(线段树+概率)

Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4465   Accepted: 1966 Description Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually exp

POJ 2151 Check the difficulty of problems (动态规划-概率DP)

Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4522   Accepted: 1993 Description Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually exp

poj 2151 Check the difficulty of problems (检查问题的难度)

poj 2151 Check the difficulty of problems http://poj.org/problem?id=2151 题意:此刻有tn道题目,有dn个队伍,知道每个队伍能答对每个题目的概率,问:冠军至少答对n(1<=n<=tn)道题目,其他队伍至少要答对一道题目的概率 dp+概率 方法: f[i][j]第i队做对第j个题的概率 g[i][j][k]第i队前j个题做对k个题的概率 状态转移方程:g[i][j][k] = g[i][j-1][k-1]*f[i][j] +

poj 2151 Check the difficulty of problems

dp[i][j][s]表示第i个人,在前j个问题解决了s个问题 dp[i][j][s]=dp[i][j-1][s-1]*p[i][j]+dp[i][j-1][s]*(1-p[i][j]); 1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<vector> 5 #include<queue> 6 #include<stack> 7 #include

POJ 2151:Check the difficulty of problems 概率DP

Check the difficulty of problems 题目连接: http://poj.org/problem?id=2151 题意: 有M (0<M≤30)个人,和T (1<T≤1000)道题目,求所有人都至少做出了一道题且其中有人做出N (0<N≤M)道或N道以上的概率 题解: 求出满足条件1(所有人都至少做出一道题目)的概率,再求出满足条件1且所有人的题数都小于N道的概率,减一下就是答案了 代码 #include<stdio.h> #include<s

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

Language: Default Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5419   Accepted: 2384 Description Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the org