zoukankan      html  css  js  c++  java
  • 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
    ",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 }
  • 相关阅读:
    红楼【建筑位置】
    红楼【人物关系】
    jenkins【shared-libraries】
    linux 安装mysql8.0 tar.xz
    MySQL 输入字符串对日期进行模糊查询
    解决kali linux 和 win10 双系统时间不一致问题
    linux idea桌面图标
    linux卸载openjdk11
    tar.xz解压
    pandas模块高性能使用方法总结
  • 原文地址:https://www.cnblogs.com/Leohh/p/7529849.html
Copyright © 2011-2022 走看看