zoukankan      html  css  js  c++  java
  • POJ 2151 概率DP

    题意:

    举办一次ACM竞赛,需要考虑两方面,1.是每个队至少都能做出1道题目,2.是冠军至少能做出n道题目。现在已知有m道题目,t支队伍,和n的值,以及每支队伍做出每道题目的概率gl[i][j],求出这次比赛能保证上面两方面都会达到的概率。

    PS:我代码中的n和m是反的。

     

    思路:

    这个题应该算是基础的概率dp了,就是一个加法原理和乘法原理,其他和普通dp一样,甚至方程更简单

    dp[i][j][k]表示第i个队伍,做前j道题目,作对k道的概率,方程很好写吧~

    我们可以把最终的答案转化成 每个队伍都做至少一道题目的概率-每个队伍都只做1~(n-1)道题的概率

    好了,就是这样了~

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 
     5 #define N 40
     6 #define M 1010
     7 
     8 using namespace std;
     9 
    10 double gl[M][N],dp[M][N][N];
    11 int n,m,t;
    12 
    13 void go()
    14 {
    15     for(int i=1;i<=t;i++)
    16         for(int j=1;j<=n;j++)
    17             scanf("%lf",&gl[i][j]);
    18     memset(dp,0,sizeof dp);
    19     for(int i=1;i<=t;i++)
    20     {
    21         dp[i][0][0]=1.0;
    22         for(int j=1;j<=n;j++)
    23         {
    24             dp[i][j][0]=dp[i][j-1][0]*(1.0-gl[i][j]);
    25             for(int k=1;k<=j;k++)
    26                 dp[i][j][k]=dp[i][j-1][k-1]*gl[i][j]+dp[i][j-1][k]*(1.0-gl[i][j]);
    27         }
    28     }
    29     double ans1=1.0,ans2=1.0;
    30     for(int i=1;i<=t;i++) ans1*=(1.0-dp[i][n][0]);
    31     for(int i=1;i<=t;i++)
    32     {
    33         double tmp=0.0;
    34         for(int j=1;j<m;j++)
    35             tmp+=dp[i][n][j];
    36         ans2*=tmp;
    37     }
    38     printf("%.3lf\n",ans1-ans2);    
    39 }
    40 
    41 int main()
    42 {
    43     while(scanf("%d%d%d",&n,&t,&m),n||m||t) go();
    44     return 0;
    45 } 
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    FZU 2112 并查集、欧拉通路
    HDU 5686 斐波那契数列、Java求大数
    Codeforces 675C Money Transfers 思维题
    HDU 5687 字典树插入查找删除
    HDU 1532 最大流模板题
    HDU 5384 字典树、AC自动机
    山科第三届校赛总结
    HDU 2222 AC自动机模板题
    HDU 3911 线段树区间合并、异或取反操作
    CodeForces 615B Longtail Hedgehog
  • 原文地址:https://www.cnblogs.com/proverbs/p/2711092.html
Copyright © 2011-2022 走看看